Search code examples
reactjsmemoizationusecallbackreact-usememoreact-memo

How to use useCallback, useMemo and React.memo when dependency is an object?


I have useMemo when one of its dependencies is an Object that I get from the server, so even when the content of the object is the same - the useMemo is called over and over again in each sync from the server because the object itself is different every time, of course it is the same for useCallback and React.memo.

How can I solve this?

I was thinking about checking manually if the new result has the same contents as the previous result and if it does - stay with the previous object reference.


Solution

  • Two options really:

    • do as you planned, i.e. don't change the object if it's deep-equal (e.g. deep-equal on npm) to the object you receive:
      const [obj, setObj] = React.useState();
      // ...
      const newObj = await getObjectFromServer();
      // Using the function form of setState to avoid races and an extra
      // dependency on `obj`:
      setObj(oldObj => equal(newObj, oldObj) ? oldObj : newObj);
      
    • depend on the fields the memo uses, not the full object:
      • Not this:
        React.useMemo(() => obj.foo + 8, [obj]);
        
      • But this:
        React.useMemo(() => obj.foo + 8, [obj.foo]);
        
      However, that may easily get cumbersome and won't help if obj.foo itself is not a primitive.