'Render prop in lists keeps remounting
I have a List component that accepts a render prop. The render function then gets passed a Component. Something like this:
function List({ render, items }) {
return (
<ul>
{items.map(() => {
return render('li');
})}
</ul>
);
}
<List items={[...]} render={(Wrapper) => {
return <Wrapper>...</Wrapper>
}}
While above example works, if I want to pass a Component to the render function as an inline function (so I can for example pass a slightly different component based on the item index) — the rendered component keeps "remounting".
function List({ render, items }) {
const [number, setNumber] = useState(null);
return (
<ul>
{items.map((item, index) => {
return render(({...props}) => {
return <TestListItem onClick={() => {
// bit of logic that's different for each item
setNumber(index)
}} {...props}/>
});
})}
</ul>
);
}
function TestListItem ({...props) {
useEffect(() => {
// function that only runs when Test List gets mounted
console.log('first render');
}, [])
return <li {...props} />
}
<List items={[...]} render={(Wrapper) => {
return <Wrapper>...</Wrapper>
}}
This is evidenced by console.log('first render') being executed every time onClick={() => { setNumber(index) }} happens.
I understand this happens because I'm passing an inline function. But I'm not sure how to do this without passing an inline function but still being able to pass props that are specific to the item index. How do I do this using render props - or maybe even using another solution?
Solution 1:[1]
Answering my own question. I fixed this by passing children (<TestListItem/>) to the render function, instead of components/elements (() => <TestListItem/>).
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | AKG |
