Home > Back-end >  Second arugument of React.memo() not working properly in react native
Second arugument of React.memo() not working properly in react native

Time:10-22

I'm trying to re render only when the minutes change using React.memo() like this:

function getCurrentTime(){
  let now = new Date();
  return ({
    'mins': now.getMinutes(),
    'secs': now.getSeconds()
  })
}


const Disp = React.memo(({ timeObj }) => { //this Component is suppose to be in another file
  return (<Text>{timeObj['mins']}</Text>);
}, (prevProp, newProp) => {

  if (prevProp['mins'] == newProp['mins'])
    return false;

  return true;
});


export default function App() {

  const [CurrentTime, setCurrentTime] = useState(() => getCurrentTime());

  useEffect(() => {
    let secTimer = setInterval(() => {setCurrentTime(getCurrentTime())}, 500);
    return () => { clearInterval(secTimer) };
  }, []);

  return (
    <View style={styles.body}>
      <Disp timeObj={CurrentTime} />
    </View>
  );
}

but for some reason it isn't working & renders every 500 ms
I've followed this tutorial

CodePudding user response:

You have your return values backward in your comparison function. From the documentation (in a comment in the code sample):

return true if passing nextProps to render would return the same result as passing prevProps to render, otherwise return false

You're doing the opposite, returning false when the minutes are the same.

Also, you're missing out the timeObj part (thanks Felix!), it should be prevProps.timeObj.mins (and the same for newProps). (Also, "props" should be plural, and generally best to write .mins rather than ['mins'].)

Instead:

const Disp = React.memo(
    ({ timeObj }) => { //this Component is supposed to be in another file
        return (<Text>{timeObj.mins}</Text>);
    },
    (prevProps, newProps) => {
        // Return true if the props are the same for rendering purposes,
        // false if they aren't
        return prevProps.timeObj.mins == newProps.timeObj.mins;
    }
);

As a side note, you can use nested destructuring if all you want is the mins from timeObj (you can do that both in the component and the comparison function, but I'd probably only do it in the component, gets confusing doing the renaming needed):

const Disp = React.memo(
    ({ timeObj: { mins } }) => { //this Component is supposed to be in another file
        return (<Text>{mins}</Text>);
    },
    (prevProps, newProps) => {
        // Return true if the props are the same for rendering purposes,
        // false if they aren't
        return prevProps.timeObj.mins == newProps.timeObj.mins;
    }
);
  • Related