首页 > 解决方案 > 避免在引用前一个状态时在 setState 中使用回调

问题描述

我仍然收到此错误,但我不明白在我的代码中怎么可能:

export default class GenericTable extends React.PureComponent {
  constructor(props) {
    super(props);

    this.state = {
      otherStuff: '',
      ...props, // rows are received on props
      sort: {
        col: 0,
        asc: true,
      },
    };
  }

  onSortChange = i => {
    const tempRows = this.state.rows;
    const tempSort = this.state.sort; // this is the line where it says about that error

    const newRows = [];
    if (tempSort.asc) {
      newRows = tempRows.sort(function(a, b) {
        if (a.cells[i] < b.cells[i]) {
          return -1;
        }
        if (a.cells[i] > b.cells[i]) {
          return 1;
        }
        return 0;
      });
    } else {
      newRows = tempRows.sort(function(a, b) {
        if (a.cells[i] > b.cells[i]) {
          return -1;
        }
        if (a.cells[i] < b.cells[i]) {
          return 1;
        }
        return 0;
      });
    }
    tempSort.col = [i];
    tempSort.asc = !tempSort.asc;
    this.setState({ rows: newRows, sort: tempSort });
  };
...
}

所以,它是tempSort声明的地方。应该如何改变它才能工作?

我看不出与 eslint 页面上描述的相似之处。

标签: javascriptreactjsecmascript-6eslintsetstate

解决方案


@Leo Messi,你不是应该准备周六对阵那不勒斯的比赛吗?:)

一边开玩笑……

您需要使用这种形式的 setState,它接受一个使用前一个状态调用的函数,以便函数内部的逻辑在相同的状态下运行。最后它应该返回新计算的状态。

import React from 'react';

export default class MyComponent extends React.PureComponent {
    constructor(props) {
        super(props);

        this.state = {
            otherStuff: '',
            ...props, // rows are received on props
            sort: {
                col: 0,
                asc: true
            }
        };
    }

    getNewState(prevState, i) {
        const tempSort = prevState.sort;
        const tempRows = this.state.rows;
        let newRows = [];

        if (tempSort.asc) {
            newRows = tempRows.sort(function(a, b) {
                if (a.cells[i] < b.cells[i]) {
                    return -1;
                }
                if (a.cells[i] > b.cells[i]) {
                    return 1;
                }
                return 0;
            });
        } else {
            newRows = tempRows.sort(function(a, b) {
                if (a.cells[i] > b.cells[i]) {
                    return -1;
                }
                if (a.cells[i] < b.cells[i]) {
                    return 1;
                }
                return 0;
            });
        }
        tempSort.col = [i];
        tempSort.asc = !tempSort.asc;
        return { rows: newRows, sort: tempSort };
    }

    onSortChange = i => {
        this.setState(prevState => {
            return this.getNewState(prevState, i);
        });
    };

    render() {
        return <p>test</p>;
    }
}

在我的 VS Code 上进行了测试,并将相关规则添加到我的.eslintrc.js. 但是,请记住,将您的状态计算逻辑放入带有prevState参数的版本中并不会阻止您引入其他问题(正如我在之前版本的答案中提到的那样,不是创建新对象,而是改变现有对象,其中第一个是预期的。我删除了答案的那部分,因为它实际上并没有解决那个特定问题,但我建议你在编辑历史记录中再次检查)。


推荐阅读