4

Have below function which is common custom hook and called from multiple places.

How this can be memoized to improve performance. (While debug on browser then observed it called multiple times). It would be also fine if fields.forEach only memoized instead of all code under custom hooks'

I tried to add a function inside the hook but, I need to return result object instead of function.

export function useListObject(fields)
{
const allData = useGetAll();
const result = {};
fields.foreach((field) =>{
  ...
  ...
  ...
  result[field]= {key, value , parameters, names}
});
return result;
}

///// component called as below

const listData = useListObject(['state','country','categoryTypes','category']); 

//Is it possible to memoize here ? so no need to memoize within custom hooks.

TechS
  • 167
  • 1
  • 5
  • 14

1 Answers1

3

You can use the useMemo hook provided by React to memoize the result of your forEach loop:

const result = useMemo(() => {
  const fieldData = {};

  fields.foreach((field) =>{
    ...
    ...
    ...
    fieldData[field] = { key, value , parameters, names }
  })
  
  return fieldData;
}, [fields]);

This way until fields changes, result will be memoized to whatever you return inside of the useMemo call.

Keith Brewster
  • 3,302
  • 2
  • 21
  • 28
  • Here `fields` is an array , Will it be comparing the value for array items and memoize based on array items OR by array reference ? In case, `fields` is new reference array but array values are same then, useMemo will able to compare by array items ? – TechS Aug 12 '21 at 15:46
  • 2
    That's a great point, if it's possible the best way to achieve this would be to keep the `fields` array as part of the state of the parent (if it's possible). That way it will be the same reference through each re-render. Here's a sandbox: https://codesandbox.io/s/silly-sunset-9vpgf?file=/src/App.js otherwise you can do other things like stringifying the array in the dependency to check equality – Keith Brewster Aug 12 '21 at 16:03
  • Thanks, it looks good idea using, `useState` , just in my case, its already used so many places and its lil tricky to make changes at all the places. Just checking if `strigify` is good option, do you mean like, `useMemo(()=>{}),[JSON.Stringify(fields)])` ? Haven't used this way but not sure if that gives any linting issue. checking this part. – TechS Aug 12 '21 at 16:31
  • There will not be much longer fields. it would be max 15. Is there performance issue if used like, `useMemo(()=>{}),[JSON.Stringify(fields)])` Or some better way to achieve ? – TechS Aug 12 '21 at 16:48
  • 1
    There's a good discussion around different implementations in this post: https://stackoverflow.com/questions/59467758/passing-array-to-useeffect-dependency-list if your data structure isn't huge `stringify`'s performance will probably be negligible, but there are a couple of other strategies presented – Keith Brewster Aug 12 '21 at 18:20