简体   繁体   中英

How to optimize my code with useMemo in React?

I have a situation in React with the useMemo() hook.

I have an array object called a . This object contains multiple objects. This array is large. When it contains b and c objects, a looks like a = [b,c] . I am doing heavy computation on array a . Here is my code snippet:

    const computedValue = useMemo(() => {
         return a.map(key,() => {
           anotherHighComputationFunc(key);
         });
    },[a])

const anotherHighComputationFunc = useMemo((key) => {
        // ..... do some expensive computation
       return someValue;
},[key]);

If a reference of a does not change, I do not compute the value again, I just return the precomputed value. If a reference of a changes then I will look into the array a to check if some key has changed its reference inside the array. If for some key reference has not changed then return the precomputed value for that key, otherwise do computation for that key.

The issue is that the rule of hook fails as I am using a hook inside another hook. So it throws me an error. Is there any other way round to do memoization at 2 levels?

The useMemo() hook won't help you here, because it has a cache size of 1, and you can't call hooks inside other hooks. In addition, you don't need to memoize the function, but the results of the call.

You can create a simple memoization wrapper using WeakMap that will allow the garbage collector to clean the values when not needed.

Note: WeakMap keys must be objects.

const weakMemo = fn => {
  const map = new WeakMap();
  
  return obj => {
    if (map.has(obj)) return map.get(obj);
    
    const res = fn(obj);
    
    map.set(obj, res);
    
    return rs;
  }
};

// the useMemo is needed here to preserve the instance of the memoized function with the cached values
const computeKey = useMemo(() => weakMemo((key) => {
  // ..... do some expensive computation
  return someValue;
}), [anotherHighComputationFunc]);

const computedValue = useMemo(() => a.map(computeKey), [a, computeKey]);

The rules of Hooks clearly state: Don't call Hooks inside loops, conditions, or nested functions. Instead, always use Hooks at the top level of your React function.

Rather than using a hook for your anotherHighComputationFunc , create a cache object which stores the values of the function and return it if it is inside the cache object.

const cache = {};

function anotherHighComputationFunc(key) {
   if (cache[key]) return cache[key];

    /** anotherHighComputation calculation here */
    cache[key] = anotherHighComputationValue;
    return anotherHighComputationValue
} 

 const computedValue = useMemo(() => {
     return a.map(key,() => {
       anotherHighComputationFunc(key);
    });
},[a])

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM