I have the following route in my App component:
<Route path ='/:id' component = {VideoPage} />
When this route is visited, I want the VideoPage component to use the :id parameter to make an axios request to an API, and then I want to update VideoPage's state and render out the information that the API returns.
This is what I'm currently doing in the VideoPage component, which doesn't work:
export default class VideoPage extends Component {
constructor(props){
super()
this.state = {
id: props.match.params.id,
mainVideo: defaultVideo
};
}
componentDidUpdate(){
axios.get(getVideo(this.state.id))
.then(res => {
console.log(res)
this.setState({
mainVideo: res.data
})
})
.catch(err => console.log(err))
}
render() {
// render several components, passing them pieces of state from this component
}
The problem is that when I call this.setState
from within componentDidUpdate, I get an infinite loop.
So how would you go about doing this (making an API call using params from ReactRouter and the )?
You have to check the change of the state you want to track in the componentDidUpdate, because otherwise, when you call setState in componentDidUpdate it will trigger the update and cause an infinite loop.
I assume you want to call the API everytime the id state is changed. You can use the prevState parameter of componentDidUpdate, refer to this link
You can check the state by comparing the prevState with current state like this
componentDidUpdate(prevProps, prevState) {
if (this.state.id !== prevState.id) {
axios.get(getVideo(this.state.id))
.then(res => {
console.log(res)
this.setState({
mainVideo: res.data
})
})
.catch(err => console.log(err))
}
}
But componentDidUpdate is invoked after change is occured, so it won't get invoked in initial render so you have to put your API call in componentDidMount too.
componentDidMount() {
this.fetchVideo()
}
componentDidUpdate(prevProps, prevState) {
if (this.state.id !== prevState.id) {
this.fetchVideo()
}
}
fetchVideo() {
axios.get(getVideo(this.state.id))
.then(res => {
console.log(res)
this.setState({
mainVideo: res.data
})
})
.catch(err => console.log(err))
}