IssueRaiser

Dancing between state and effects - a real-world use case

I started this as a gist but Dan mentioned that this would be a good discussion issue so here goes. I've been writing with and refactoring code into hooks for a while now. For 95% of code, they are great and very straight-forward once you get the basic idea. There are still a few more complex cases where I struggle with the right answer though. This is an attempt to explain them. ## The use case This is a real-world use case from an app I'm building: interacting with a list items. I've simplified the examples into codesandboxes though to illustrate the basic idea. Here's the first one: https://codesandbox.io/s/lx55q0v3qz. It renders a list of items, and if you click on any of them, an editable input will appear to edit it (it doesn't save yet). The colored box on the right will change whenever an item rerenders. If you click around in the items, you can see that when changing the edited item, all items rerender. But the `Row` component is wrapped with `React.memo`! They all rerender because the `onEdit` is new each time the app renders, causing all items to rerender. ## Maintaining callback identity We want `onEdit` to be same function for all future renders. In this case, it's easy because it doesn't depend on anything. We can simply wrap it in `useCallback` with an empty dependencies array: ```js let onEdit = useCallback(id => { setEditingId(id); }, []); ``` Now, you can see clicking around only rerenders the necessary items (only those colors change): https

Posted by jlongster on Mar 28, 2019, 4:41 PM

Tags

Related issues

Raise real-world problems, find people facing the same issue, and discuss solutions.4,000 issues0 comments

github (SaaS)

Dancing between state and effects - a real-world use case

jlongsterMar 28, 2019, 4:41 PM

I started this as a gist but Dan mentioned that this would be a good discussion issue so here goes. I've been writing with and refactoring code into hooks for a while now. For 95% of code, they are great and very straight-forward once you get the basic idea. There are still a few more complex cases where I struggle with the right answer though. This is an attempt to explain them. ## The use case This is a real-world use case from an app I'm building: interacting with a list items. I've simplified the examples into codesandboxes though to illustrate the basic idea. Here's the first one: https://codesandbox.io/s/lx55q0v3qz. It renders a list of items, and if you click on any of them, an editable input will appear to edit it (it doesn't save yet). The colored box on the right will change whenever an item rerenders. If you click around in the items, you can see that when changing the edited item, all items rerender. But the `Row` component is wrapped with `React.memo`! They all rerender because the `onEdit` is new each time the app renders, causing all items to rerender. ## Maintaining callback identity We want `onEdit` to be same function for all future renders. In this case, it's easy because it doesn't depend on anything. We can simply wrap it in `useCallback` with an empty dependencies array: ```js let onEdit = useCallback(id => { setEditingId(id); }, []); ``` Now, you can see clicking around only rerenders the necessary items (only those colors change): https

Comments (0)

No comments yet. Start the discussion.

Comment on this issue