Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should I use useMemo in hooks?

Tags:

reactjs

I created useBanner hooks

const useBanner = (array, yardage) => {
  const [bannArr, setBannArr] = useState(array.slice(0, yardage));
  const [bannListIndex, setBannIndex] = useState(1);

  return {
   ....
  };
};

Am I doing the right thing and the props throw in useState. It’s permissible to use useBanner.

const Banner= ({
  array,
  yardage
}) => {
  const { bannForth, bannBeck, bannArr } = useBanner(array, yardage);
  return (
    ...
  );
};

when props will change here. Will change the state in useBanner. or is it considered anti-patterns I have to write all this in useMemo

const useBanner = (array, yardage) => {
  const [bannArr, setBannArr] = useState([]);
  const [bannListIndex, setBannIndex] = useState(1);

 useMemo(() => {
    setBannArr(array.slice(0, yardage));
    setBannIndex(1);
  }, [array, yardage]);


  return {
   ....
  };
};
like image 890
Silicum Silium Avatar asked Nov 07 '22 15:11

Silicum Silium


1 Answers

Yes, custom hooks are possible in React. Here is separate document discussing custom hooks.

But exactly you sample may require additional code depending on what is your final goal.

  1. If you want initialize state only once, when component Banner is first created, you can just do as in your first sample

    const Banner= ({
        array,
        yardage
    }) => {
        const { bannForth, bannBeck, bannArr } = useBanner(array, yardage);
        return (
          ...
        );
    };
    

    This will work perfectly. But if props array and yardage will change, this will not be reflected in component. So props will be used only once as initial values and then will not be used in useBanner even if changed (And it doesn't matter whether you'll use useBanner or useState directly). This answer highlight this.

  2. If you want to update inital values on each props change, you can go with useEffect like below

    const Banner= ({
        array,
        yardage
    }) => {
        const { bannForth, bannBeck, bannArr, setBannArr } = useBanner(array, yardage);
        useEffect (() => {
            // setBannArr should also be returned from useBanner. Or bannArr should be changed with any other suitable function returned from useBanner.
            setBannArr(array.slice(0, yardage)); 
        }, [array, yardage, setBannArr])
        return (
          ...
        );
    };
    

    In this case Banner component can control state itself and when parent component change props, state in Banner component will be reset to new props.

Here is small sample to showcase second option.

like image 118
Fyodor Avatar answered Nov 15 '22 07:11

Fyodor