I have the following loop (simplified):
const ExpensiveItems = useMemo(() => {
return items.map((item, idx) => {
const style = {
marginTop: V_GAP,
...(idx === items.length - 1 && { marginBottom: V_GAP }),
};
return <ExpensiveComponent style={style} item={item} />;
});
}, [items]);
return loading ? <div>Loading...</div>
: <div>{ExpensiveItems}</div>
Whenever, items changes will the ExpensiveComponent function be called N times where N is the length of items. Or will React diff the props first and only call the ExpensiveComponent function again if and only if the props have changed?
This is possibly premature optimization, but if the ExpensiveComponent function will be called N times each time the items array changes, I'd like to avoid calling it N times if possible, since usually at most 1 item in the items array will change at a given time.
So the question is: If re-calling items.map will call the ExpensiveComponent function N times, is there a way to optimize this map function further so that if a single item in the items array changes, I don't do that?
Whenever, items changes will the ExpensiveComponent function be called N times where N is the length of items
Yes, it will, unless ExpensiveComponent is a PureComponent (which only re-render if the props change).
But this is a strange problem to have - the rendering of components shouldn't be expensive at all, unless you have many of them and they have an unreasonable number of children each. Otherwise, if the rendering is expensive, you should refactor them so that they only perform whatever the expensive calculation is when they really need to, and not on every re-render.
Just for example, don't do
const ExpensiveComponent = ({ style, item }) => {
const result = someBigCalculation(item);
// ...
return <div>{result}</div>
}
Instead do
const ExpensiveComponent = ({ style, item }) => {
const [result, setResult] = useState();
useEffect(() => setResult(someBigCalculation(item)), [item]);
In decently structured code, running the top level of a component to re-render shouldn't be expensive in the vast majority of situations, though there are a few exceptions.