Search code examples
javascriptreactjschildren

Proper React-ful way to handle a function in a parent component that will only act on selected child components?


So to simplify it to an extent, I have two React components, one that's a child of the other. Lets say they're ItemTable and ItemRow. ItemTable has many ItemRows. ItemTable gets invoked and receives an array of items. For each item in this array, an ItemRow gets created inside ItemTable. I want to be able to select certain ItemRows, each one tied to one item, and perform one specific action on each selected item at the ItemTable level. I have a checkbox on each row for selection, and a button in ItemTable to start performing the action on each selected item. There are two ways I can think of doing this, and I'm not sure which would be the 'proper' way of doing it in React.

Option 1: Have an empty array initialized at the ItemTable state. Each time a checkbox in ItemRow gets checked, it calls a handle function passed down from the parent ItemTable state that either adds or removes it from ItemTables array. In other words, the list of items to act on is being kept track of at the ItemTable level, and then when the button to process the actions is clicked, it parses the array and performs the action on each item.

Option 2: Have a variable initialized to false at the LicenseRow level upon creation. When checked, it changes the LicenseRow's state to true. When unchecked, false. When the button at the LicenseTable level is checked, it goes to each child, and if it's marked as true (checked), process that item.

I'm going back on forth on which I think would be the better way to do it. I know React is a top-down data flow, and so I'm leaning towards option 2, but I feel like managing the list of children should be the job of the parent. I'm not sure if either way is necessarily 'wrong', but in your opinion, what's the better way to process these items?


Solution

  • Both strategies are valid and there is no right or wrong answers here. In my experience, Option 1 is the more common approach to take.

    It has a few other benefits over the Option 2 as well:

    • Generally I find it easier to set up and debug (I believe you need to use a ref to access anything on the child).
    • On larger collections, it will perform better as it already knows which items are selected before processing. Option 2 would have to enumerate the entire collection, even if only one item was actually selected.
    • Having the parent own the state enables you to do more with it more easily. For example, you can disable the button if no items are selected for processing.

    I know React is a top-down data flow, and so I'm leaning towards option 2

    In my opinion the data is still only flowing down in Option 1. The parent make the decision about what data to change when the callback is fired and passes it down to the children.

    In the end the choice is yours, so good luck. :)