【发布时间】:2020-05-24 23:30:54
【问题描述】:
我正在玩 reactjs,这就是我正在做的事情: 正在从 API 检索数据并显示数据 使用 axios 调用 API。 我知道 axios 调用是异步的并且是基于 Promise 的。
我的理解是在 react 'setState' 中只能在组件挂载后调用 (发生在 componentDidMount 中)。 所以对 API 的调用是在 'componentDidMount' 中进行的
我不清楚的是:为什么会这样,为什么要显示数据?
我正在阅读 here 'render' 在 'componentDidMount' 完成之前被触发
所以鉴于“render”在“componentDidMount”之前,我很困惑为什么数据加载并显示正常?
我还查看了this site,它使用一些标志来确定数据是否已加载,然后决定是否显示微调器 我也不必做任何这样的事情 因此,虽然它确实显示数据,但我相信还有更多...
代码如下:
class StudentsPage extends React.Component{
constructor(props){
super(props);
this.state = {
isLoaded: false,
studentListArray: []
}
}
componentDidMount(){
/** now get results from api call and need to set the result to the state of this class */
/** setting state MUST happen using setState and no other way - this is important */
/** NOTE below call to setState will ONLY modify the attribute 'studentListArray' of state
* if there were other attributes / properties in state they would not get impacted / modified
* so setState is more like setters for individual properties
* you can change multiple properties in one setter OR call setState for each property you want to change !
*/
/** define the endpoint to be called */
const baseUrl = process.env.REACT_APP_API_URL + "/studentList/";
axios.get(baseUrl).then(({data}) => {
this.setState(
{ studentListArray: data }
);
})
}
render(){
return(
<React.Fragment>
<table className="table">
<thead>
<tr>
<th>Sudent ID</th>
<th>Student subject</th>
</tr>
</thead>
<tbody>
{this.state.studentListArray.map((student) => {
return (<tr>
<td>{student.id}</td>
<td>{student.subject}</td>
</tr>);
})}
</tbody>
</table>
</React.Fragment>
);
}
}
【问题讨论】:
-
这完全符合预期。我建议在你的
render方法中加入一些console.logs,看看this.state.studentListArray最初是什么(空数组),然后在你调用this.setState之后。它可能以您描述的方式出现的原因是 b/c 最初您的数组是空的,因此它不会破坏或呈现任何内容,一旦您收到回复并更新studentListArray,它将立即重新渲染。服务器的响应是即时的,因此可以快速重新渲染。 -
另外,一种证明一切按预期工作的方法,将
this.state.studentListArray的初始值更改为null并注意代码中断,因为axios.get调用尚未完成获取和更新第一次渲染之前的状态。 -
为什么有效? ... 异步结果修改状态(使用 setState) - 任何
state或props更改都是重新渲染的原因(更新视图) - 这样您就可以说使用setState(使用不同的数据然后当前)强制重新渲染(显示具有新数据/状态的新视图) -
谢谢,我想我错过的是'setState'会再次调用'render',而且我对方法执行的顺序也有误(componentDidMount 然后渲染(我的假设)与实际顺序渲染 >> componentDidMOunt >> 渲染(如果状态改变)
-
我将针对相同代码的变体发布一个单独的问题,但失败了
标签: javascript reactjs