Reputation: 761
I wrote a piece of code that I don't quite remember how it works, embarrassing to say.
The state is as below:
state={
api:[
{
id: 1,
purpose: "For the Android phone",
link: "playgoogle/GooglePlay",
status: "1"
},
{
id: 2,
purpose: "For the Android phone",
link: "playgoogle/GooglePlay",
status: "0"
}
]
}
And this is the snippet of code that I don't quite understand.
activateAPI=(id)=>{
this.setState(prev => ({
api: prev.api.map(api => api.id === id ? { ...api, status: 1 } : api)
}))
this.changeStatus(id,1);
}
I understand that a value is passed into the activateAPI as id but I don't quite understand how the prev
and api: prev.api
works here. I understand that the api
inside the map
is like a foreach where it checks whether the current item's id in the json array matches the function id then what does {...api,status:1}
mean?
Any clarification would be much appreciated. Thank you for reading.
Upvotes: 1
Views: 2318
Reputation: 522
The nature of setState
is async. What you've written is pretty clear that when you call setState
with its callback signature. Internally once the callback completes, React returns the callback to setState
. And here's what you're doing,
(state, props) => stateChange
Above is the true signature of the setState
that React provides.
State is a reference to the component state at the time the change is being applied.
For more info link
Also when you use spread operator, it spreads the object and updates the prop that is changed. So when you do {...api, status:1}
. It will compare the API object from the initial one and updates the status
value to 1.
Remember this will be the shallow comparison. For updating nested state objects you need to go to the nested level to observe proper state update.
Upvotes: 2
Reputation: 5999
What the Spread operator does is that it creates a new object.
So in this case when you are doing {...api, status: 1}
a new object is getting created with all the keys present in api
object and then overriding the status
value with 1
when api.id === id
is true.
let x = {key: "Key", val: 1, val2: 22}
//spread and update the value, it'll only update `val` all other values wil be as is
console.log({...x, val: 2})
//the original object will be as is
console.log(x)
let y = {z: {key: "Key", val: 3}, z1: 2}
//assign y to y1 by spreading
let y1 = {...y}
y1.z.val = 4;
//z.val in both y and y1 will be modified because spread will not spread deep objects
console.log(y1)
console.log(y)
Coming to the arrow function in setState
will accept a function as first parameter. React will pass state
and props
as params to the passed function. This way you will be able to access the state
in order to update it by using old state.
Below is the setState
function
setState(updater, [callback])
The first argument is an updater function with the signature:
(state, props) => stateChange
state is a reference to the component state at the time the change is being applied. It should not be directly mutated. Instead, changes should be represented by building a new object based on the input from state and props. Hope this helps.
Upvotes: 1
Reputation: 1143
api: prev.api.map(api => api.id === id ? { ...api, status: 1 } : api)
That mean , When mapping array if it find the api with the id matched, it with return the new api object with property 'status' change to '1' . If not it will just return the old api object
sorry for my bad english :D hope it help
Upvotes: 1