无法在componentDidMount()中从api调用呈现内容

时间:2018-02-01 02:44:37

标签: reactjs

这是我在React工作时遇到的问题的简化版本。当我在componentDidMount()内进行提取调用并使用有效负载更新状态时,如下所示:

componentDidMount(){
    fetch("/api/endpoint").then(data => {
        return data.json();
        }).then(json => {
            this.setState({
                data: json
            });
    });
}

并在render()

中呈现出来
render(){
    return(
        <p>{this.state.data.title}</p>
    )
}

我收到错误this.state.data is undefined。我把它包裹在条件运算符周围,如下所示:

{ this.state.data !== undefined ? <p>{this.state.data.title}</p> : null }

但我的问题是,如果componentDidMount()render()之前触发,那么this.state.data怎么可能未被定义?

3 个答案:

答案 0 :(得分:0)

componentDidMount()render()之后运行。您需要在构造函数

中正确初始化状态
class YourComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = { data: {title: "" } };
  }

  componentDidMount(){
      fetch("/api/endpoint").then(data => {
          return data.json();
          }).then(json => {
              this.setState({
                  data: json
              });
      });
  }
  render(){
    return(
        <p>{this.state.data.title}</p>
    )
  }

}

答案 1 :(得分:0)

  

但我的问题是,如果componentDidMount()在render()之前触发,那么this.state.data怎么会被定义?

componentDidMount之前或之后render点火的顺序在这里并不重要。 componentDidMount具有异步效果。假设它总是在render之前触发,那么会发生什么:

componentDidMount正在运行。它运行fetch。运行fetch不会使浏览器等待fetch返回并执行setState。相反,fetch将请求发送到服务器,并返回 promise ,当服务器的响应返回时, promise 将被实现。

履行承诺时运行的代码是作为参数传递给.then()的函数。由于您的setState来电位于.then()内,因此只有在响应可用时才会运行。

与此同时,您的浏览器会继续拨打render。来自服务器的响应可能已经或可能没有返回并解决了承诺(很可能它不会返回,因为网络比执行代码的处理器慢)。因此,在render尚未定义的情况下调用this.state.data。因此,您需要考虑dataundefinedrender的状态。

答案 2 :(得分:0)

  

但我的问题是,如果componentDidMount()在render()之前触发   如何定义this.state.data?

您假设/理解componentDidMount生命周期函数在渲染错误之前触发,componentWillMount在渲染之前触发,componentDidMount在渲染方法之后触发。现在您可能会说,因为componentWillMount在渲染之前被触发,我可以在componentWillMount中移动我的fetch调用,因此我不必在render方法中添加一个检查,但这不对。即使您的请求在呈现之前被触发,但在执行呈现函数之前响应可能并不总是可用,并且由于所有这些都发生asynchronously,您需要在呈现方法中添加对数据的检查

render(){
    return(
        <p>{this.state.data? this.state.data.title: null}</p>
    )
  }

查看Use componentWillMount or componentDidMount lifecycle functions for async request in React问题以获取更多详情