Answer the question
In order to leave comments, you need to log in
How to make react redraw only one element when state is updated?
Hello. Please tell me, I create an array of objects in state, and generate child components using map, and when one field changes, everything is re-rendered. Is there any way to optimize this? It seemed to me that this is what the key field is indicated for, but it does not help.
Here is an example code:
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>
)
}
Answer the question
In order to leave comments, you need to log in
With each call setNewItemData
, you get a new array items
. which you shove into setItem
. Each time you call setItem
, your entire function will be executed, which means that items.map
, and each of MyItem
. If you want to draw only MyItem
, then modify its internal state, and not the state of the parent.
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>
);
};
When the parent component changes, it renders all child elements
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question