Reputation: 1255
My component renders 4 times and it seems to be caused by fetching and multiple setState functions. How can I make it use just one setState() including all fetched data?
I have already tried to create one function instead of one, create three variables to store fetch results and pass them to setState but it did not help me. Thanks in advance!
class DuelList extends React.Component {
state = {
duels: [],
users: [],
datasets: []
};
fetchDuels = () => {
axios.get("http://127.0.0.1:8000/api/duel/user/",
{'headers': {'Authorization': `Token ${localStorage.getItem('token')}`}})
.then(res => {
this.setState({
duels: res.data
});
});
};
fetchUsers = () => {
axios.get("http://127.0.0.1:8000/api/user/",
{'headers': {'Authorization': `Token ${localStorage.getItem('token')}`}})
.then(res => {
this.setState({
users: res.data
});
});
};
fetchDatasets = () => {
axios.get("http://127.0.0.1:8000/api/dataset/",
{'headers': {'Authorization': `Token ${localStorage.getItem('token')}`}})
.then(res => {
this.setState({
datasets: res.data
});
});
};
componentDidMount() {
this.fetchDuels();
this.fetchUsers();
this.fetchDatasets();
}
render() {
return (
<div>
<Duels data={this.state.duels}/> <br/>
<h2> Add duel </h2>
<AddDuelForm users={this.state.users} datasets={this.state.datasets} requestType="post" articleID={null}
btnText="Challenge"/>
</div>
);
}
}
export default DuelList;```
Upvotes: 2
Views: 427
Reputation: 281726
Make use of Promise.all
and setState once all the apis resulted in success response like
class DuelList extends React.Component {
state = {
duels: [],
users: [],
datasets: []
};
fetchDuels = () => {
return axios.get("http://127.0.0.1:8000/api/duel/user/",
{'headers': {'Authorization': `Token ${localStorage.getItem('token')}`}})
};
fetchUsers = () => {
return axios.get("http://127.0.0.1:8000/api/user/",
{'headers': {'Authorization': `Token ${localStorage.getItem('token')}`}})
};
fetchDatasets = () => {
return axios.get("http://127.0.0.1:8000/api/dataset/",
{'headers': {'Authorization': `Token ${localStorage.getItem('token')}`}})
};
componentDidMount() {
Promise.all([this.fetchDuels(), this.fetchUsers(), this.fetchDatasets()]).then(([duels, users, datasets]) => {
this.setState({
duels,
users,
datasets
})
});
}
render() {
return (
<div>
<Duels data={this.state.duels}/> <br/>
<h2> Add duel </h2>
<AddDuelForm users={this.state.users} datasets={this.state.datasets} requestType="post" articleID={null}
btnText="Challenge"/>
</div>
);
}
}
export default DuelList;
Upvotes: 1
Reputation: 67296
You would need to group and resolve all the promises together:
fetchDuels = () => {
return axios.get("http://127.0.0.1:8000/api/duel/user/",
{'headers': {'Authorization': `Token ${localStorage.getItem('token')}`}})
};
fetchUsers = () => {
return axios.get("http://127.0.0.1:8000/api/user/",
{'headers': {'Authorization': `Token ${localStorage.getItem('token')}`}})
};
fetchDatasets = () => {
return axios.get("http://127.0.0.1:8000/api/dataset/",
{'headers': {'Authorization': `Token ${localStorage.getItem('token')}`}})
};
componentDidMount() {
const promises = [this.fetchDuels(), this.fetchUsers(), this.fetchDatasets()];
Promise.all(promises).then(([ duelsReponse, usersResponse, datasetsReponse ]) => {
this.setState({ duels: duelsReponse.data, users: usersReponse.data, datasets: datasetsResponse.data });
});
}
This way, you reduce the number setState
calls.
Upvotes: 3