Reputation: 4496
How can one modify state in a parent component, and pass it down as props to the children, but only re-render those children when the modified state changes?
My basic setup currently works, but it's causing some unnecessary re-renders. The parent components gets information from the URL (using react-router hooks) and modifies it, and then passes that down as props to its children. The component looks like this:
const myComponent = () => {
const { dataType } = useParams();
const { search } = useLocation();
/// These functions help me transform that data into something more manageable
const y = queryString.parse(search).collection;
const { collections, gqlQuery } = getCollections(dataType);
const collection = collections.find(x => x.value === y);
return (
<MyChild collection={collection} /> ... This component is re-rendering unnecessarily.
)
};
How can I ensure that when the URL doesn't change (the dataType
and search
values that are pulled using react-router) the child components that receive derived data ALSO won't unnecessarily re-render?
Upvotes: 0
Views: 774
Reputation: 19204
The first step would be to make sure that the reference to collection
variable changes only when one of the dependencies change:
useMemo(() => {
const y = queryString.parse(search).collection;
const { collections, gqlQuery } = getCollections(dataType);
const collection = collections.find(x => x.value === y);
}, [search, dataType]);
The second would be to make sure that the component only re-renders when it receives new props:
import { memo } from 'react';
function Child() {
}
export default memo(Child);
You can also use the second argument for memo
to customise what is compared.
function Child(props) {
}
function areEqual(prevProps, nextProps) {
/*
return true if passing nextProps to render would return
the same result as passing prevProps to render,
otherwise return false
*/
}
export default React.memo(Child, areEqual);
React.memo - Docs React.useMemo - Docs
PS: Note that React is usually super fast with re-renders. Use these only as a performance enhancement after measuring their impact. There is a chance it has worse performance than before
Upvotes: 1