Wrong idea about useCallback and useMemo
Closed this issue · 1 comments
Hello,
I don't know your blog, just been shared this article usememo-and-usecallback by one of my colleagues and I think you misinterpreted the real problem of mismatch renders and thus the benefit of useCallback and useMemo.
So with your example:
var A = () => doSomething(blah);
var B = useCallback(() => doSomething(blah), [blah]);
Yes, both A and B declare a new function in memory on every react render, plus B declares an Array. Then that goes to the virtual DOM. Up to this point I would say that this is free but let me develop.
The expensive part come after at the point where React will check for you if the result of the render 1 is equal to the render 2, useCallback
will see that the dependencies did not change and return the same function, making sure B === B. Done.
In the second case, it will see that A !== A', so it will flag this node as changed. Then it will have to define if what kind of change it is and find out the impact of it, if this prop is passed to a child, it will render this child, if it is passed to a DOM element, it will check what kind of attribute and go through the update. For the best case it's an event attached to a DOM element, it will simply unbind the previous even and bind the new one. In the worst case it is actually used in a useEffect of a child and result in another DOM change, triggering a DOM render, layout reflow, repaint, blocking the UI for a couple of ms at best. That will add up for each of your components. All that because you did not want to declare an extra array?
An expensive render is a render that will result in React having to touch the DOM. The goal of an optimised React application is to avoid this step at all cost, because Javascript runtime is way cheaper that anything that will happen once the browser have to take over.
I would prefer to run 100 times all the component renders of my application rather than touching the DOM once for each of them. And This is just about the web, which usually run in pretty permissive environments. But react also applies to react-native, where assigning an array in a javascript VM is nothing, but blocking 100 times your UI to update 100 views can crash your application.
Sure learning how React and the browser work is a tedious process and understanding why useCallback
and useMemo
are important can not be obvious at first. But telling people that you just declare as many functions in memory anyway and that hooks are not real optimisation is so wrong that I had to correct you.
I hope I have made some sense to you and that you correct your article so I don't have another colleague pointing me to your website.
Thank you very much,
Best regards,
Julien Tome
Thanks for reaching out. I'm afraid I don't have a lot of time to explain this to you, but I think you're confusing renders with commits. Just because react calls your render method doesn't mean that it will update the DOM. And you can't get around necessary DOM updates. If the DOG needs to be updated, then it needs to be updated. Also, changing event handlers doesn't actually result in any DOM updates either thanks to React's built-in event delegation system. As for side-effects, you should be setting your dependencies array properly regardless of unnecessary rerenders to avoid bugs, and if you do then it doesn't matter how many times component rerenders anyway.
So no, my article is not mistaken or misleading so I won't be changing it. Thanks anyway.