简体   繁体   中英

Should I apply useCallback/ useMemo for all functional components?

I have a question that should I apply useCallback/ useMemo for all function/ variable declarations for all functional components. As far as I know, useCallback/ useMemo makes function/ variable declarations are not run again after component update. These functions/ variables are only redefined when their dependency changed. It makes rendering job of React use less effort on redefined something unchanged. It just compares object(s) (dependencies of functions/ variables with useCallback/ useMemo) when these objects changed. I think comparing job is faster than redefining.

Example of using useCallback hook:

const onOpenEnd = useCallback(() => {
    if (BTSheetRef && BTSheetRef.current) BTSheetRef.current.open()
  }, [BTSheetRef, BTSheetRef.current]);

Does I misunderstand anything? Thank in advance.

Not for all the function/ variable, it should use for some scenarios

useCallback

  • This is useful when passing callbacks to optimized child components that rely on reference equality to prevent unnecessary renders.

If the child component should not be rendered when the parent gets rendered, then you should have to use this hook, why? since we are passing the same function to the child, child component will not get rendered unnecessarily.

check some code here

const ChildComponent = React.memo(() => {
  const date = new Date().getTime();
  return (
    <div>
      {date}
    </div>
  );
});

export default function App() {
  const [time, setTime] = React.useState(null);

  //if we use this one child component will rerender only if the dependacies of the useCallback gets changed,
  //when dependancies change rect will return a new function, otherwise it will retun the old function.
  const fn = React.useCallback(() => {
  }, []);

  // if we use below fn as a prop to the child, child will rerender on every rendering of this component.
  //because react will give us a new function on every renderings.
  /* 
    const fn = () => {
    } 
  */

  return (
    <div>
      <ChildComponent fn={fn}/>

      <br />
      <p>changing the numbers means that child component gets rerendered</p>
      <button onClick={() => setTime(new Date().getTime())}>change state</button>
    </div>
  );
}

useMemo

  • You may rely on useMemo as a performance optimization, not as a semantic guarantee.

Means that if you have to calculate a heavy calculation, then you should relay on this hook, why? just because the calculation is not gonna perform on every rendering.

check some code here

export default function App() {
  const [time, setTime] = React.useState(null);

//memorizing result of complex calculations
  const heavyComputedValue = React.useMemo(() => {
    //some heavy calculations
    let val = new Date().getTime();
    for (let a = 0; a < 1000000000; a += 1) {
      val += a;
    }

    return val;
  }, []);

//-------without memorizing results of complex calculations----------//
// enabling this will show you component update gets lagging due to calculation happens every time unnecessarily
/*
  let val = new Date().getTime();
  for (let a = 0; a < 1000000000; a += 1) {
    val += a;
  }
  const heavyComputedValue = val;
  */
//--------------------------------------------------------//

  return (
    <div>
      <p>Time: {time}</p>
      Heavy computed value: {heavyComputedValue}
      <br />
      <button onClick={() => setTime(new Date().getTime())}>
        change state
      </button>
    </div>
  );
}

You're still defining a function with every render when using useCallback and useMemo, those functions just memoize the result of the functions you define within useCallback and useMemo, so that you don't have to run them very often. Also, when not using useCallback or useMemo and rendering your component for the second time, the original function you defined gets garbage collected (freeing up memory space) and then a new one is created. However with useCallback the original function wont get garbage collected and a new one is created, so you're (slightly) worse-off from a memory perspective.

Because of that, it's often better to just use a regular function within a react component. Unless the function you're defining is expensive to run and you want to memoize the results, it makes more sense to not use useMemo or useCallback.

Here's a really good article explaining this: https://kentcdodds.com/blog/usememo-and-usecallback

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