I want to design my app like this, but I'm worried if that'll cause double re-render:
function Parent() {
const normalizedData = useSelector(state => state.normalizedData);
const dispatch = useDispatch();
useEffect(() => {
let sortedData = mySort(normalizedData);
dispatch({ type: 'UPDATE_SORTED_DATA', sortedData });
});
return <Child />;
}
function Child() {
const sortedData = useSelector(state => state.sortedData);
return sortedData.map(...);
}
So, when I make a change to normalizedData, Parent would re-render, causing Child to re-render, but the change of sortedData would also make Child re-render, would that make Child re-render twice?
Because of this concern, I have not put sortedData into redux in the past, and I just passed it down to Child as a prop, but as the app grows, the prop drilling become increasingly tedious - lots of sub components need access to sortedData, so I really want to be able to put it into redux, is it ok to do?
Thanks!!
Yes, that would cause two renders, because that's how React works in general. Parent rendering will always cause Child to render by default unless you specifically do something to avoid the child rendering, and then Child will later queue its own render.
My first advice would be to prefer deriving data if possible (preferably using memoized selector functions) rather than calculating that derived data and stuffing it into the store separately.
My other main thought is that unless it's seriously affecting performance, don't worry about this too much. Focus on writing an app that does what you need first, _then_ profile performance in a production build and see if there are really issues.
Hi @markerikson thanks for your answer!
If I use a vanilla react prop, does it cause double re-renders when normalizedData is changed? One from Parent re-render, one from prop change? My guess is no, because the code looks really benign, but I don't know why it doesn't re-render twice...
function Parent() {
const normalizedData = useSelector(state => state.normalizedData);
let sortedData = mySort(normalizedData);
return <Child sortedData={sortedData} />;
}
function Child({ sortedData }) {
return sortedData.map(...);
}
cause double re-renders
Maybe, it's in <StrictMode> and using DEV?
As for the first example, React.memo would help.
Most helpful comment
Maybe, it's in
<StrictMode>and using DEV?As for the first example,
React.memowould help.