Reputation: 699
Please watch the following code. I know how to fetch data and render the component with the data after the component mounts. But the component needs to fetch other data to re-render when the prop changes.
Before, I can use componentWillReceiveProps()
to fulfill this easily, but this method is not recommended now and setState()
can't be called in componentDidUpdate()
. I don't know how to solve this problem.
class HotList extends Component {
constructor(props) {
super(props);
this.state = {
loading: true,
songs: [],
};
}
componentDidMount() {
this.fetchHotList(this.props.platform);
}
// The following method is not recommended for use in current React version.
// componentWillReceiveProps(nextProps) {
// this.fetchHotList(nextProps.platform);
// }
// setState() can't be called in componentDidUpdate()
componentDidUpdate(prevProps) {
this.fetchHotList(this.props.platform);
}
fetchHotList(platform) {
this.setState({
loading: true,
});
fetch(`/api/hot_list/${platform}`, {
credentials: 'include',
}).then(res => res.json())
.then(json => {
if (json.status === 'ok') {
this.setState({
loading: false,
songs: json.data.songs,
});
}
})
.catch(err => console.error(err));
}
render() {
const { songs } = this.state;
return (
<div>
{
this.state.loading ?
<Icon type="loading" /> :
<SongList songs={songs}
/>
}
</div>
);
}
}
export default HotList;
Upvotes: 1
Views: 1291
Reputation: 2438
You should check preProps when using componentDidUpdate() to avoid infinity loop
componentDidUpdate(prevProps) {
if (prevProps.platform !== this.props.platform)
this.fetchHotList(this.props.platform);
}
I think maybe your this
is this of fecth callback function.
Well you can change a little code:
fetchHotList(platform) {
const that = this;
that.setState({
loading: true,
});
fetch(`/api/hot_list/${platform}`, {
credentials: 'include',
}).then(res => res.json())
.then(json => {
if (json.status === 'ok') {
that.setState({
loading: false,
songs: json.data.songs,
});
}
})
.catch(err => console.error(err));
}
Upvotes: 1
Reputation: 5566
Not using setState
in componentDidUpdate
is more of a recommendation than a hard rule. You can do it, but you must be careful or you might end up in a componentDidUpdate-setState loop. As per the docs:
You may call setState() immediately in componentDidUpdate() but note that it must be wrapped in a condition like in the example above, or you’ll cause an infinite loop.
As per the docs above, you can do something like this:
componentDidUpdate(prevProps) {
if (prevProps.platform != this.props.platform)
this.fetchHotList(this.props.platform);
}
Upvotes: 3