Javascript 不确定react中的此异步调用为何工作

Javascript 不确定react中的此异步调用为何工作,javascript,reactjs,Javascript,Reactjs,我正在玩reactjs,下面是我正在做的: 我正在从API检索数据并显示数据 使用axios调用API。 我知道axios调用是异步的,并且基于承诺 我的理解是,只有在安装组件后才能调用react中的“setState” (发生在componentDidMount中)。 因此,对API的调用是在“componentDidMount”中进行的 我不清楚的是:为什么这样做,为什么我要显示数据 我读到“render”在“componentDidMount”完成之前被触发 因此,鉴于“render”在“

我正在玩reactjs,下面是我正在做的: 我正在从API检索数据并显示数据 使用axios调用API。 我知道axios调用是异步的,并且基于承诺

我的理解是,只有在安装组件后才能调用react中的“setState” (发生在componentDidMount中)。 因此,对API的调用是在“componentDidMount”中进行的

我不清楚的是:为什么这样做,为什么我要显示数据

我读到“render”在“componentDidMount”完成之前被触发

因此,鉴于“render”在“componentDidMount”之前,我不明白为什么数据加载和显示良好

我还研究了它在哪里使用一些标志来确定数据是否已加载,然后决定是否显示微调器 我也不必做这样的事情 所以,虽然它确实显示数据,但我相信这其中还有更多

代码如下:

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>
    );
}
}
class StudentsPage扩展React.Component{
建造师(道具){
超级(道具);
此.state={
isLoaded:false,
studentListArray:[]
}
}
componentDidMount(){
/**现在从api调用获取结果,并需要将结果设置为此类的状态*/
/**设置状态必须使用setState而不是其他方式发生-这一点很重要*/
/**注意:下面对setState的调用只会修改state的属性“studentListArray”
*如果状态中有其他属性/属性,则它们不会受到影响/修改
*所以setState更像是单个属性的setter
*您可以在一个setter中更改多个属性,也可以为要更改的每个属性调用setState!
*/
/**定义要调用的端点*/
const baseUrl=process.env.REACT_APP_API_URL+“/studentList/”;
get(baseUrl).then({data})=>{
这是我的国家(
{studentListArray:data}
);            
})
}
render(){
返回(
Sudent ID
学生科目
{this.state.studentListArray.map((student)=>{
返回(
{student.id}
{学生.科目}
);
})}
);
}
}

装载基于类的组件时,其生命周期方法按以下顺序执行:

  • constructor()
  • 静态getDerivedStateFromProps()
  • render()
  • componentDidMount()
  • 在您的情况下,在装入
    StudentPage
    组件后,它会立即尝试获取数据,然后触发组件更新/重新呈现

    当组件重新呈现时,它将按以下顺序调用以下生命周期方法:

  • 静态getDerivedStateFromProps
  • shouldComponentUpdate()
  • render()
  • getSnapShotBeforeUpdate()
  • componentdiddupdate()
  • 如果在
    render()
    componentDidMount()
    componentdiddupdate()中放置断点或简单的
    console.log()
    ,您将能够更清楚地看到这一点

    这纯粹是我的猜测,但您调用的(我假设是本地的)服务器可能会更快地响应您期望的数据,因此在第一次装载时数据似乎随时可用


    如果您希望了解有关React生命周期方法的更多信息,请毫不犹豫地参考。

    这完全符合预期。我建议在
    render
    方法中放置一些
    console.log
    s,查看
    this.state.studentListArray
    最初是什么(空数组),然后在调用
    this.setState
    之后。它可能以您描述的方式出现的原因是b/c最初您的数组是空的,因此它不会中断或呈现任何内容,并且一旦您得到响应并更新
    studentListArray
    ,它将立即重新呈现。服务器的响应是即时的,因此可以快速重新渲染。另外,一种方法可以证明一切都按预期工作,将
    this.state.studentListArray
    的初始值更改为
    null
    ,并观察代码是否中断,因为
    axios.get
    调用在第一次渲染之前尚未完成获取和更新状态。它为什么工作。。。异步结果修改状态(使用设置状态)-任何
    状态
    道具
    更改都是重新渲染(更新视图)的原因-这样,您可以说使用
    设置状态
    (与当前数据不同)强制重新渲染(使用新数据/状态显示新视图)谢谢,我想我错过的是“setState”将再次调用“render”,而且我对方法执行顺序(componentDidMount,然后render(我的假设)与实际顺序render>>componentDidMount>>render(如果状态更改)的看法也是错误的我将针对同一代码的一个变体发布一个单独的问题,但是哪个失败了Hanks,是的,我缺少的是当状态发生变化时会再次调用render,并且我认为方法执行的顺序是错误的(componentDidMount,然后render)