2
votes

This question is specifically about the newer react redux hooks, particularly useSelector and useDispatch. Say you have one component that is a list and another component that is a list item. The list component contains a list of the list items.

You need to use a piece of the redux store in the list item and dispatch an action also in the list item. The data that you need from the store and the dispatch function will be the same for each item in the list.

Should you use those hooks in the items themselves or use the hooks in the parent list component and pass the store and dispatch function down to the items via props? Does it have some performance impact to do the useDispatch and useSelector hook on each item in the list?

Edit to add code example:

const List = () => (
  <div>
      {someArray.map((item) => {
        return (
          <ListItem/>
        );
      })}
  </div>
);

const ListItem = () => {
  const myState = useSelector((state) => state);
  const dispatch = useDispatch();
  // Do these here or in the parent and pass down as props?


  return (
      <div />
  );
};
1
Do you have a small amount of code for context here? This is hard to answer in the abstract. The short answer is "It depends".tadman

1 Answers

3
votes

There's never a perf issue with calling useDispatch(), anywhere, as that doesn't cause components to re-render.

The question for useSelector is which components need access to which data, and what components will re-render if a given bit of data changes.

In general, components should always try to select the smallest amount of state needed for them to render themselves.

Both the "select all data in the parent" and "select item IDs in the parent, select items by ID in the children" approaches are viable. If the data in the list may be updated somewhat frequently, you should probably prefer selecting items by ID inside each list component.

However, if the parent is also re-rendering whenever any of the individual items change, that will force all list item components to re-render unless you actively optimize them (such as wrapping the list items in React.memo()).

Ideally, updating one item in the list should either not cause the parent to re-render, or it does re-render and the children are memoized so only the one list item will actually re-render itself.

For more details, see my posts: