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;
}
);