【问题标题】:Accessing a promise with the componentDidMount使用 componentDidMount 访问 Promise
【发布时间】:2016-07-12 07:15:11
【问题描述】:

我正在访问从我的模拟 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>
    );
}

模拟 API 如下所示

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

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

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

【问题讨论】:

  • 你的意思是console.log()总是显示一个空数组吗?还是什么也没有渲染?
  • console.log() 显示 [] - 渲染很好 - 组件按预期显示警告,因为正在将空数组传递给预期的 StudentListStatistics 组件。我在 StudentListStatistics 组件中设置了所需的 PropType 验证,因此我收到以下警告“警告:失败的 propType:所需的道具 studentBodyStatistics 未在 StudentStatisticsRow 中指定。检查 StudentListStatistics 的渲染方法。”
  • console.log 显示一个空数组是有道理的,但我认为(最终)您的StudentListStatistics 会呈现模拟数据(最初它收到一个空数组,因为这是组件的初始状态)。
  • 但是一旦 ComponentDidMount 被触发,console.log 应该会显示正在返回的数据。我同意最初它是一个空数组,但即使在触发 componentDidMount 之后,也会返回 []
  • 如果您使用箭头函数 (=&gt;),请不要使用 self = this,因为它们具有词法 this 范围。不要将延迟承诺和包含逻辑混为一谈 - 而是构建一个 delay 原语并使用它。您不需要在文字中重复对象属性,{ studentsStatistics:studentsStatistics } 只是 {studentsStatistics}。不要使用debugger,在开发者工具中使用断点(在你的代码中忘记调试器会去优化你的代码)

标签: reactjs promise


【解决方案1】:

问题有两个方面:

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

要解决这个问题并记录模拟数据,您需要首先等待承诺解决,然后还要等待setState 确认状态已更改(passing it a callback function):

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

  promise.then(studentsStatistics => {
    this.setState({
      studentsStatistics: studentsStatistics
    }, () => {
      console.log(this.state.studentsStatistics);
    }
  });
}

我认为这也意味着您的 StudentListStatistics 组件最初将使用空数组作为输入来呈现。只有当 Promise 被解决后,它才会收到模拟的数据。

【讨论】:

  • 谢谢,有道理,一旦快速跟进问题 - 我仍然收到 warning.js?8a56:44Warning: Failed propType: Required prop studentBodyStatistics 未在 StudentStatisticsRow 中指定。检查StudentListStatistics 的渲染方法。渲染方法不应该基于状态已更新的事实“重新渲染”吗?
  • @usr28765526 听起来好像还有其他问题,可能在您的财产声明中。您是否将名为 studentBodyStatistics 的属性传递给您的 StudentStatisticsRow 组件?
  • 是的 - 我刚刚想通了...... - 现在完美运行 - 令人沮丧的是,我无法想象回调问题正在盯着我看。再次感谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-22
  • 1970-01-01
  • 2019-01-25
  • 2020-09-17
  • 1970-01-01
  • 2016-10-29
相关资源
最近更新 更多