使用 componentDidMount 访问 Promise

usr*_*526 2 promise reactjs

我正在访问从我的模拟 API 返回的承诺。React 组件如下所示

import React from 'react';
import StudentListStatistics from './StudentListStatistics';
import StudentStatisticsApi from '../../api/mockStudentApi';

class AboutPage extends React.Component {
  constructor(props, context) {
      super(props, context);
      this.state = {
          studentsStatistics: []
      };

  }

componentDidMount() {
    StudentStatisticsApi.getAllStudentsStatistics().then(
        studentsStatistics => {
            this.setState({
                studentsStatistics: studentsStatistics

            });
            debugger;
        }
    );

    console.log(this.state.studentsStatistics);
}

render() {
    return (
        <div>
            <h2>Student Body Statistics</h2>
            <StudentListStatistics studentsStatistics={this.state.studentsStatistics}/>
        </div>
    );
}
Run Code Online (Sandbox Code Playgroud)

模拟 API 看起来像这样

class StudentApi {
static getAllStudentsStatistics() {
    return new Promise((resolve, reject)=> {
        setTimeout(()=> {
            resolve(Object.assign([], studentsStatistics));
        }, 1000);
    });
}
Run Code Online (Sandbox Code Playgroud)

我不确定为什么 this.state.studentsStatistics 始终是一个空数组。如果我单步执行代码,那么在 then 回调中我的模拟 API 会正确返回 StudentsStatistics 数组。

有人可以指出我可能缺少什么吗?

rob*_*lep 5

这个问题有两个方面:

  • getAllStudentsStatistics()是异步的,这意味着它最终会产生结果,但不是立即产生;
  • setState()this.state也是“异步”的,因为它在被调用后不会立即改变。

要解决这个问题并记录模拟数据,您需要首先等待 Promise 解析,然后等待确认setState状态已更改(通过向其传递回调函数):

componentDidMount() {
  let promise = StudentStatisticsApi.getAllStudentsStatistics();

  promise.then(studentsStatistics => {
    this.setState({
      studentsStatistics: studentsStatistics
    }, () => {
      console.log(this.state.studentsStatistics);
    }
  });
}
Run Code Online (Sandbox Code Playgroud)

我认为这也意味着您的StudentListStatistics组件最初将使用空数组作为输入进行渲染。只有在 Promise 得到解决后,它才会收到模拟数据。