Reputation: 1734
I created a React App with AXIOS. I need to get some JSON data from back end and change the State with that data. When I get the object and mapping to my state, the state is only setting for the last element of the object. So I can only see the last element in the state. How I can get all the elements to the state?
My API call is as follows
API.post('viewallusers', [], config)
.then(({ data }) => {
const allUsers = data.response.AllUsers;
allUsers
.map(user => {
return (
this.setState({
data: [
createData(
user.name,
user.id,
user.email
)
]
})
)
})
})
.catch((err) => {
console.log("AXIOS ERROR: ", err);
})
JSON data:
{response :
{AllUsers :
0 : {name: "Amy", id: 1, email: "myEmail1"},
1 : {name: "Doris", id: 2, email: "myEmail2"},
2 : {name: "Jase", id: 3, email: "myEmail3"}
}
}
I expect the the state "data" is to be set as follows:
data : [
createData("Amy",1,"myEmail1"),
createData("Doris",2,"myEmail2"),
createData("Jase",3,"myEmail3")
]
But the actual state after getting the JSON data is
data : [
createData("Jase",3,"myEmail3")
]
How can I solve this?
Upvotes: 0
Views: 62
Reputation: 28685
It probably happens because setState
doesn't do a deep merge. So if you have in state
state = {
key1: 123,
key2: {
test1: 1,
test2: 2
}
}
And you do
this.setState({
key2: {
test1: 4
}
})
You will end up with
state = {
key1: 123,
key2: {
test1: 4
}
}
You have to do instead:
this.setState((ps) => ({
key2: {
...ps.key2,
test1: 4
}
}));
Similar approach works if value for key2
is array. Or alternatively you can first map all the data and then do a setState
as suggested in other answer.
Upvotes: 1
Reputation: 45106
You need to first map the data then set entire state.
API.post('viewallusers', [], config)
.then(({ data }) => {
this.setState({
data: data.response.AllUsers.map(user => (createData(user.name, user.id, user.email)))
})
})
Or use callback version of setState
and manually merge state.data
(NOT recommended in this particular case)
API.post('viewallusers', [], config)
.then(({ data }) => {
data.response.AllUsers.forEach(user => {
this.setState(prev =>
({...prev, data: [prev.data, createData(user.name, user.id, user.email)]})
)
})
})
Upvotes: 1