I want to not re-render my component on certain paths, trying to do this using React.memo and checking the current path using the withRouter HOC.
The compare function in React.memo does not get called.
function compare(prevProps, nextProps) {
console.log(prevProps,nextProps)
return (prevProps.location.pathname !== '/' && nextProps.location.pathname !== '/')
}
export default React.memo( withRouter(MyComponent), compare);
just use it like this
function compare(prevProps, nextProps) {
console.log(prevProps,nextProps)
return (prevProps.location.pathname == nextProps.location.pathname)
}
export default withRouter(React.memo(MyComponent, compare));
the comparison you had has a flow, if you are in the main page where the route is / then the compare function will always return false causing re-render all the time(just like if memo didn't exist in the first place), and if your are in a sub-route other than / like /articles then the comparison will always return true causing the component to re-render al the time, just like if memo didn't exist in the first place.
What you want is a comparison that depends on new and old props having equal things which leads to save a re-render or having non-equal things which leads to a new re-render to render the fresh data for you.
So the comparison should be something like
prevProps.location.pathname == nextProps.location.pathname
Thanks for your question, it was very helpful to me two months ago.
memo function take a component and a function that will be called to decide if React needs to re-render or not, if the function returns true the component will not re-render, any way if the function returns false then the props are now different and React do re-render to your component.
Now: to access the pathname correctly in the function passed to memo then memo should be wrapped with withRouter and not the opposite, withRouter wrap a component (it doesn't know it's memorized version of a component or not, it just wraps it) and pass it the routing props.
The function passed to memo as a second argument now can access the previous and new props and do the comparison as we talked earlier (where each props as inside it the fully routing details that you want).
import { memo } from 'react';
function propsAreEqualBasedOnPathname(prevProps, nextProps) {
return prevProps.location.pathname == nextProps.location.pathname;
}
withRouter(memo(MyComponent), propsAreEqualBasedOnPathname);
Finally, take extra care for how the comparison is made inside the compare function because some mistakes might prevent your component from re-rendering in the future forever.
I found using memo with withRouter really important to improve the performance of React components, especially if the component was a page full of details and fetching logic that can cost you some time to render, so every re-render you save, increases your page performance.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With