let myData = [
{ id: 1, data: 'Foo' },
{ id: 2, data: 'Bar' }
]
export default function Test(){
let [items, setItem] = useState(myData);
let setNewItemData = (itemId, data) => {
let newItems = items.map(item => {
if(item.id !== itemId){
return item;
}
return { ...item, data }
});
setItem(newItems)
}
console.log('Render main Component');
return (
<>
{
items.map(item => {
return (
<MyItem key={item.id} item={item} setNewItemData={setNewItemData}></MyItem>
)
})
}
</>
)
}
export default function MyItem({ item, setNewItemData }) {
console.log('Render MyItem');
return (
<button onClick={ () => { setNewItemData(item.id, 'New value') } }>{item.data}</button>
)
}
setNewItemData
у тебя получается новый массив items
. Который ты пихаешь в setItem
. При каждом вызове setItem
, выполнится вся твоя функция, а значит и items.map
, и заново отрендерится каждый из MyItem
. Если хочешь что рисовался только MyItem
, то модифицируй его внутренний стейт, а не стейт родителя.const Item = ({ item }) => {
const [item, setItem] = useState(itemProp);
const updateItem = useCallback(() => {
setItem((item) => ({
...item,
count: item.count + 1
}));
}, []);
return (
<div onClick={updateItem}>
{item.title} {item.count}
</div>
);
};
export default const MyItem = React.memo(({ item, setNewItemData }) => {
....
});
let [items, setItems] = useState(myData);
const setNewItemData = useCallback((itemId, data) => {
setItems((items) => {
return items.map(item => {
if (item.id !== itemId) {
return item;
}
return {...item, data}
});
});
}, [setItems]);