Is it possible to apply React.memo to an array of ponents with a for loop?
Say I have the following three ponents:
const Item1 = (props) => {
const { index } = props;
return (
<div>{index}</div>
);
}
const Item2 = (props) => {
const { index } = props;
return (
<div>{index}</div>
);
}
const Item3 = (props) => {
const { index } = props;
return (
<div>{index}</div>
);
}
Could I do this in my App ponent?
const App = (props) => {
const items = [Item1, Item2, Item3];
let itemarray = [];
let index = 0;
for (const item of items) {
const MemoizedItem = React.memo(item);
itemarray.push(<MemoizedItem key={index} index={index} />);
index++;
}
return (
<div>
{itemarray}
</div>
);
}
I know I can hard code React.memo for each of the three items (see below), but I'd like to be able to do it iteratively.
const Item1 = React.memo((props) => {
const { index } = props;
return (
<div>{index}</div>
);
});
//...same for Item2 and Item3
Is it possible to apply React.memo to an array of ponents with a for loop?
Say I have the following three ponents:
const Item1 = (props) => {
const { index } = props;
return (
<div>{index}</div>
);
}
const Item2 = (props) => {
const { index } = props;
return (
<div>{index}</div>
);
}
const Item3 = (props) => {
const { index } = props;
return (
<div>{index}</div>
);
}
Could I do this in my App ponent?
const App = (props) => {
const items = [Item1, Item2, Item3];
let itemarray = [];
let index = 0;
for (const item of items) {
const MemoizedItem = React.memo(item);
itemarray.push(<MemoizedItem key={index} index={index} />);
index++;
}
return (
<div>
{itemarray}
</div>
);
}
I know I can hard code React.memo for each of the three items (see below), but I'd like to be able to do it iteratively.
const Item1 = React.memo((props) => {
const { index } = props;
return (
<div>{index}</div>
);
});
//...same for Item2 and Item3
Share
Improve this question
asked Aug 22, 2020 at 1:06
AmosAmos
4122 gold badges4 silver badges14 bronze badges
2 Answers
Reset to default 13Calling React.memo in the middle of rendering is a bad idea. It will have the exact opposite effect of the intended goal. Instead of being able to skip rendering, you will force it to do extra rendering.
When you call React.memo and pass in a ponent, what's returned is a new type of ponent. Not a new instance, a new type. The main way react tells what has changed from one render to the next is by paring the types on ponents. If the type changed, it's assumed to be different, and therefore the old ponent is unmounted and the new one is remounted. Every time App renders, it creates brand new types of ponent, which means nothing can be saved from one render to the next.
I'd remend just using React.Memo where you implement Item1, Item2, Item3. Eg:
const Item1 = React.memo((props) => {
const { index } = props;
return (
<div>{index}</div>
);
})
But if you absolutely need to do it dynamically, then you'll need to make sure you only do it once, which basically means you need to memoize the memoization:
const App = (props) => {
const items = [Item1, Item2, Item3];
const memoizedItems = useMemo(() => {
return items.map(item => React.Memo(item));
}, [])
let itemarray = [];
let index = 0;
for (const MemoizedItem of memoizedItems) {
itemarray.push(<MemoizedItem key={index} index={index} />);
index++;
}
return (
<div>
{itemarray}
</div>
);
}
Edit: This answer is not rememded. It pletely destroyes the point of React Memo. Check the accepted answer as it explains the correct way.
I think that would work. And I would rather use array's map
method to do it.
const App = (props) => {
const items = [Item1, Item2, Item3];
return (
<div>
{items.map((item, index) => {
const MemoizedItem = React.memo(item);
return <MemoizedItem key={index} index={index} />
}}
</div>
);
}