Reputation: 4296
I am trying to change the state of my app without overriding the values that haven't changed. I am doing so using the spread operator, but something is going wrong.
Here is my base state : useState({data : [{name : undefined , project : []}] });
With setState
i want to just add names but keep the project array empty since it didn't change.
setManager(prevState => ({...prevState , data : res.data}))
After performing setState the new state looks like this :
[
{name: "John doe"},
{name: "Jane Doe"}
]
as you can see the default state is completely overridden.
res.data looks like this by the way :
[
{name: "john doe"},
{name: "jane doe"}
]
Upvotes: 0
Views: 1318
Reputation: 8418
By setManager(prevState => ({...prevState , data : res.data}))
you're simply overriding your earier 'main' data
property.
data
is an array, new values are in array ... simply concat
them
setManager(prevState => ({...prevState ,
data : prevState.data.concat( res.data )
}))
After that you should have
[
{name: undefined , project : []},
{name: "john doe"},
{name: "jane doe"}
]
... but probably you wanted to manage names and project separately:
const [manager, setManager] = useState({
data: {
name: undefined,
project: []
}
});
... or even
const [manager, setManager] = useState({
name: undefined,
project: []
});
This way you don't need to 'address' this data with 'intermediatory' .data
<Component names={manager.name} />
... not by {manager.data.name}
.
Of course updating only name
needs different code
setManager(prevState => ({
...prevState,
name : prevState.name.concat( res.data )
}))
...prevState
prevents deleting project
propertyname
should be initialized with []
, not undefined
If you have separate states 'slices' then no need to use one common state, use many useState
declarations.
Upvotes: 2
Reputation: 15146
You inited your state with an Array, not an Object, that's the reason for the behavior.
Change this from
useState({data : [{name : undefined , project : []}] });
to
useState({data : {name : undefined , project : []} });
Upvotes: 1
Reputation: 3079
Probably what you need is:
const [manager, setManager] = useState({
data: [{ name: undefined, project: [] }]
});
setManager(prevState => ({
data: prevState.data.map((item, index) => ({ ...item, ...res.data[index] }))
}));
However, if you're just storing an array of "items", then your state should look more like:
const [manager, setManager] = useState([{ name: undefined, project: [] }]);
setManager(prevState =>
prevState.data.map((item, index) => ({ ...item, ...res.data[index] }))
);
Also, the way how you're gonna merge prev and incoming data depends on many things and maybe you need some more sophisticated way of storing state.
Upvotes: 1