React:在Ajax回调中设置状态

时间:2018-05-23 01:50:33

标签: javascript jquery ajax reactjs

我是React的新手,对Javascript很新,所以我怀疑我犯了一个简单的错误。但是,我无法成功应用我在网上找到的任何修补程序,所以现在我需要就我的具体问题寻求帮助。

我将一些ajax提取到几个如下所示的辅助方法中:

function getIncomes(callback) {
$.ajax({
    url: '/get_incomes/January',
    type: 'GET',
    success: callback
})}

我想调用这些方法并使用其响应中的数据来设置我的组件状态。然后我想用状态数据渲染一个表。不幸的是,我只是得到一个null。以下是我的组成部分:

    class ExpensesGrid extends React.Component {
    constructor(){
        super();
        this.state= {incomes:{}, expenses:{}, savings:{}};
    }

    componentDidMount() {
        getIncomes(function(i){ this.setState({incomes: i})});
    }

    render() {
        return (
            <div className="expenses_grid">
                <table>
                    <tr><th>Incomes</th><th>Default Value</th><th>Actual Value</th></tr>
                    {this.state.incomes.map(row => <ExpensesGridrows row={row}/>)}
                </table>
            </div>
        )
    }
}

最后这是我的错误:

enter image description here

2 个答案:

答案 0 :(得分:1)

总体而言,问题是this.setState()发生在jQuery函数中,而不是发生在具有完全不同范围的组件本身中。我建议将getIncomes()包裹在诸如Promise之类的内容中,或者只使用Fetch并返回已解决的成功响应值,这样您就可以利用then()来执行{ {1}}成功进行API调用并完全避免回调结构。

尝试将回调更改为lambda this.stateState()而不是=>。这有助于确保您可以访问组件的范围,然后function。我建议您在所有组件中执行此操作,以始终确保您可以访问正确的setState。使用this时,function() {}的值会在其内部显示不同的值,并且将不再提供对this等方法的访问权限。您还可以使用对象扩展语法setState将当前状态...this.state的特定更新合并。

同样@RohithMurali建议,您要确认incomes的默认数据类型/值。目前还不清楚它是如何从服务器进入的,但是incomes只能用于数组,因此默认为对象Array.prototype.map()会导致初始加载时出现错误。 / p>

<强> getIncomes():

{}

<强> ExpensesGrid:

function getIncomes() {
  return new Promise((resolve, reject) => {
      $.ajax({
        url: '/get_incomes/January',
        type: 'GET',
        success: function(response) {
            return resolve(response);
        },
        error: function(err) {
            return reject(err);
        }
      });
  });
}

获取(替代ajax):

componentDidMount() {
  getIncomes()
      .then(i => this.setState({ ...this.state, incomes: i }))
      .catch(err => console.log(err);
}

希望这有帮助!

答案 1 :(得分:0)

尝试将构造函数中的状态初始化更改为

this.state= {incomes:[], expenses:{}, savings:{}};

即使在api调用返回之前,渲染也会起作用,此时收入应该是一个空数组,这样地图就可以用于0长度数组而不是对象。