I have a table (parent element) which fetches users and render each row as it\'s own component. Row in a table contains checkbox.
Goal is to be able to use checkbox
Here is an optimized function that will toggle an item without re rendering the entire list and using a list from useState:
import React, { useEffect, useState } from 'react';
const Parent = () => {
//list is created and maintained in parent
const [list, setList] = useState([
{ id: 1, val: true },
{ id: 2, val: true },
]);
//toggle is id to indicate what item to toggle
const [toggle, setToggle] = useState();
useEffect(() => {
if (toggle) {
//setting toggle will not re render until
// function is finished so no infinite loop
setToggle();
//here we can toggle the item from the list
setList(
list.map(item =>
item.id === toggle
? { ...item, val: !item.val }
: item
)
);
}
}, [list, toggle]);
//combining parent container with parent presentational
// for simplicity
return (
<div>
{list.map(item => (
<ItemContainer
key={item.id}
item={item}
//pass setToggle as item clicked
itemClicked={setToggle}
/>
))}
</div>
);
};
const ItemContainer = React.memo(function Item({
item,
itemClicked,
}) {
//toggeling item with id 1 will not log
// for item with id 2
console.log('in item render:', item.id);
return (
<pre onClick={() => itemClicked(item.id)}>
{JSON.stringify(item, undefined, 2)}
</pre>
);
});
export default Parent;
Here is an example of how to do it with useReducer.