如何使用来自 React Router 的路由参数发出 axios 请求,然后根据响应更新状态?

How do I make an axios request using a route parameter from React Router, then update state based on the response?

我的 App 组件中有以下路由:

<Route path ='/:id' component = {VideoPage} />

访问此路由时,我希望VideoPage组件使用:id参数向API发出axios请求,然后我想更新VideoPage的状态并渲染出API returns.

这是我目前在 VideoPage 组件中所做的,但不起作用:

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
    }

问题是,当我从 componentDidUpdate 中调用 this.setState 时,出现无限循环。

那么你会怎么做呢(使用来自 ReactRouter 和 的参数进行 API 调用)?

你必须在componentDidUpdate中检查你想要跟踪的状态的变化,否则,当你在componentDidUpdate中调用setState时,它会触发更新并导致死循环。

我假设您想在每次更改 id 状态时调用 API。可以使用componentDidUpdate的prevState参数,参考这个link

您可以像这样通过比较 prevState 和当前状态来检查状态

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))
  }
}

但是 componentDidUpdate 是在更改发生后调用的,因此它不会在初始渲染中被调用,因此您必须将 API 调用也放在 componentDidMount 中。

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))
}