这是我在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
怎么可能未被定义?
答案 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
。因此,您需要考虑data
中undefined
为render
的状态。
答案 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问题以获取更多详情