在ajax请求更改状态后,react组件不会重新加载

时间:2017-12-21 09:55:20

标签: ajax reactjs state axios

如果有人问过并回答我很抱歉,但是我一直在搜索并找不到答案。这是我第一次提出Ajax请求所以我确信我做的事情有点不对,任何帮助或最佳实践建议都会受到赞赏。

问题是我的反应页面加载了所有组件为空。来自Docs:

  

在此方法(componentDidMount)中调用setState()将触发额外渲染

虽然在我正在展示的示例中,我正在调用一个调用componentDidMount的函数,但我希望它具有相同的功能。并且,以防我通过将所有逻辑放入componentDidMount来测试它,并且我得到完全相同的行为。所以,我希望暂时空屏,或者暂时显示硬编码状态,但是当通过ajax接收状态时重新渲染。但是,它永远不会重新渲染。如果我通过按下按钮添加或删除项目来手动触发页面上的状态更改,我会立即看到来自我的ajax请求的所有数据。

当状态是硬编码时,一切正常。

从React Docs和这里,我看到大多数人在componentDidMount中放置了ajax请求,所以这就是我启动它的地方。如果可以的话,我试图将所有请求保存在单独的文件中,但即使我删除了loadEntries函数和getEntries函数,并将所有处理放入componentDidMount,我也会遇到同样的问题。如果它很重要,我们只讨论导入20个左右的对象,类似于硬编码状态的对象。

我很感激帮助。如果我做了一些愚蠢的话,请告诉我!

// My higher Order Component
import React, {Component} from 'react';
import Today from '../pages/Today';

export default class TodayContainer extends Component {
  constructor(props) {
  super(props);

  this.loadEntries = this.loadEntries.bind(this);

  this.state = {goalItems: [{entry_type: 1, date: "2017-12-20", id: 3, content: "other good stuff", completed: 1}],
                targetItems: [{entry_type: 2, date: "2017-12-20", id: 3, content: "Fix my hat", completed: 1}],
                successItems: [{entry_type: 3, date: "2017-12-20", id: 3, content: "Petted Cat"}],
                quoteItem: {entry_type: 4, date: "2017-12-20", id: 1, content: "This is a quote.", author: "me"}};
  }

componentDidMount() {
  this.loadEntries();
}

loadEntries() {
  let goalArray = [];
  let targetArray = [];
  let successArray = [];
  let quote = {};
  let scheduleArray = [];

Network.getEntries().then((entries) => {
  for (let entry of entries.data) {
    switch (entry.entry_type_id) {
      case 1:
          goalArray.push(entry);
          break;
      case 2:
          targetArray.push(entry);
          break;
      case 3:
          successArray.push(entry);
          break;
      case 4:
          quote = entry;
          break;
      case 5:
          scheduleArray.push(entry);
    }
  }
});

  let stateInit = {
    goalItems: goalArray,
    targetItems: targetArray,
    successItems: successArray,
    quoteItem: quote,
    scheduleItems: scheduleArray
  };

  this.setState(stateInit);
  }


//My Network File.
import axios from 'axios';

export function getEntries(){
  return axios.get('http://localhost:8000/api/entry');
}

2 个答案:

答案 0 :(得分:0)

我想你只想在请求的then块中移动let stateInit ... this.setState代码,以便在请求完成后执行。

答案 1 :(得分:0)

您的 setState 调用正在解析 Network.getEntries 的承诺之前执行。所以你必须在然后

中调用它
loadEntries() {
  let goalArray = [];
  let targetArray = [];
  let successArray = [];
  let quote = {};
  let scheduleArray = [];

Network.getEntries().then((entries) => {
  for (let entry of entries.data) {
    switch (entry.entry_type_id) {
      case 1:
          goalArray.push(entry);
          break;
      case 2:
          targetArray.push(entry);
          break;
      case 3:
          successArray.push(entry);
          break;
      case 4:
          quote = entry;
          break;
      case 5:
          scheduleArray.push(entry);
    }
  }

  let stateInit = {
    goalItems: goalArray,
    targetItems: targetArray,
    successItems: successArray,
    quoteItem: quote,
    scheduleItems: scheduleArray
  };

  this.setState(stateInit);
});
}