admin管理员组文章数量:1402813
I have a react hooks function that has a state object apiDATA
. In this state I store an object of structure:
{
name : "MainData", description: "MainData description", id: 6, items: [
{key: "key-1", name : "Frontend-Test", description: "Only used for front end testing", values: ["awd","asd","xad","asdf", "awdr"]},
{key: "key-2", name : "name-2", description: "qleqle", values: ["bbb","aaa","sss","ccc"]},
...
]
}
My front end displays the main data form the object as the headers and then I map each item in items
. For each of these items I need to display the values
and make them editable. I attached a picture below.
Now as you can see I have a plus button that I use to add new values
. I'm using a modal for that and when I call the function to update state it does it fine and re-renders properly. Now for each of the words in the values
I have that chip with the delete button on their side. And the delete function for that button is as follows:
const deleteItemFromConfig = (word, item) => {
const index = apiDATA.items.findIndex((x) => x.key === item.key);
let newValues = item.value.filter((keyWord) => keyWord !== word);
item.value = [...newValues];
api.updateConfig(item).then((res) => {
if (res.result.status === 200) {
let apiDataItems = [...apiDATA.items];
apiDataItems.splice(index, 1);
apiDataItems.splice(index, 0, item);
apiDATA.items = [...apiDataItems];
setApiDATA(apiDATA);
}
});
};
Unfortunately this function does not re-render when I update state. And it only re-renders when I update some other state. I know the code is a bit crappy but I tried a few things to make it re-render and I can't get around it. I know it has something to do with React not seeing this as a proper update so it doesn't re-render but I have no idea why.
I have a react hooks function that has a state object apiDATA
. In this state I store an object of structure:
{
name : "MainData", description: "MainData description", id: 6, items: [
{key: "key-1", name : "Frontend-Test", description: "Only used for front end testing", values: ["awd","asd","xad","asdf", "awdr"]},
{key: "key-2", name : "name-2", description: "qleqle", values: ["bbb","aaa","sss","ccc"]},
...
]
}
My front end displays the main data form the object as the headers and then I map each item in items
. For each of these items I need to display the values
and make them editable. I attached a picture below.
Now as you can see I have a plus button that I use to add new values
. I'm using a modal for that and when I call the function to update state it does it fine and re-renders properly. Now for each of the words in the values
I have that chip with the delete button on their side. And the delete function for that button is as follows:
const deleteItemFromConfig = (word, item) => {
const index = apiDATA.items.findIndex((x) => x.key === item.key);
let newValues = item.value.filter((keyWord) => keyWord !== word);
item.value = [...newValues];
api.updateConfig(item).then((res) => {
if (res.result.status === 200) {
let apiDataItems = [...apiDATA.items];
apiDataItems.splice(index, 1);
apiDataItems.splice(index, 0, item);
apiDATA.items = [...apiDataItems];
setApiDATA(apiDATA);
}
});
};
Unfortunately this function does not re-render when I update state. And it only re-renders when I update some other state. I know the code is a bit crappy but I tried a few things to make it re-render and I can't get around it. I know it has something to do with React not seeing this as a proper update so it doesn't re-render but I have no idea why.
Share Improve this question asked Apr 28, 2020 at 10:30 George PontaGeorge Ponta 3133 silver badges16 bronze badges 2-
FWIW, you only need a single
.splice
call:apiDataItems.splice(index, 1, item);
– Felix Kling Commented Apr 28, 2020 at 10:40 - Yes I had that before but I just broke it down hoping it will do something :)). Thank you for the observation anyways. – George Ponta Commented Apr 28, 2020 at 10:41
2 Answers
Reset to default 8It is not updating because you are changing the array items
inside apiDATA
, and React only re-render if the pointer to apiDATA
changes. React does not pare all items inside the apiDATA
.
You have to create a new apiDATA
to make React updates.
Try this:
if (res.result.status === 200) {
let apiDataItems = [...apiDATA.items];
apiDataItems.splice(index, 1);
apiDataItems.splice(index, 0, item);
setApiDATA(prevState => {
return {
...prevState,
items: apiDataItems
}
});
}
Using splice
isn't a good idea, since it mutates the arrays in place and even if you create a copy via let apiDataItems = [...apiDATA.items];
, it's still a shallow copy that has original reference to the nested values.
One of the options is to update your data with map
:
const deleteItemFromConfig = (word, item) => {
api.updateConfig(item).then((res) => {
if (res.result.status === 200) {
const items = apiDATA.items.map(it => {
if (it.key === item.key) {
return {
...item,
values: item.value.filter((keyWord) => keyWord !== word)
}
}
return item;
})
setApiDATA(apiData => ({...apiData, items});
}
});
}
本文标签: javascriptReactJS Updating array inside object state doesn39t trigger rerenderStack Overflow
版权声明:本文标题:javascript - ReactJS: Updating array inside object state doesn't trigger re-render - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744277333a2598477.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论