I want to update an state object userInfo which contains an array named work which is an array of objects
My Database object userInfo looks like this
{
"_id":"61a6a1d64707c03465eae052",
"fullName": "Md Nurul Islam",
"works":
[
{
"isEditing": false,
"_id": "61a6a1d64707c03465eae053",
"company": "Amazon Logistics",
"position": "Sortation Associate",
"isCurrent": true
},
{
"isEditing": false,
"_id":"61a6a1d64707c03465eae054",
"company": "The Rani Indian Takeway",
"position": "Customer Service Assistant",
"isCurrent": false,
}
]
}
But I don't want update the database, i just want to update the state userInfo in frontend to go editing mood, for this when the user clicks edit next to work section, the properties isEditing will be toggled.
Below is my code
const [userInfo, setUserInfo] = useState(user);
const workToggleHandler = (work) =>
{
setUserInfo((prev) => {
prev.works.map((p) => {
if (p._id === work._id) {
p.isEditing = !p.isEditing;
}
return p;
});
return prev;
});
With this code, my state object is updated But my components are not re-rendered
CodePudding user response:
you can put into the useEffect when particular state is update then that effect will call
useEffect(()=>{ your code will go here }[userInfo]),
CodePudding user response:
I just changed my code on workToggleHandler function and its working completely as i want. Below my code
const [userInfo, setUserInfo] = useState(user);
const workToggleHandler = (work) => {
setUserInfo({
...userInfo,
works: userInfo.works.map((p) => {
if (p._id === work._id) {
p.isEditing = !p.isEditing;
}
return p;
}),
});
};
CodePudding user response:
React does not look at the data of the object but rather on the pointer of the object. Since this is not changed (only "prev" is edited, no new object with a new object address), it doesn't not rerender. A solution would be to copy the object.
let newUserInfo = Object.assign({}, prev);
newUserInfo.works.map((p) => {
if (p._id === work._id) {
p.isEditing = !p.isEditing;
}
return p;
});
return newUserInfo;
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
Disclaimer: Maybe a deep copy is necessary....