为了账号安全,请及时绑定邮箱和手机立即绑定

在 React 中引用之前的状态时在 setState 中使用回调

在 React 中引用之前的状态时在 setState 中使用回调

月关宝盒 2022-12-22 15:08:32
我正在对一个表进行排序,它应该按字母顺序对列进行排序,按字母顺序反转并在每次调用该方法时返回到原始形式。这是我的代码:export default class GenericTable extends React.PureComponent {  constructor(props) {    super(props);    this.state = {      otherStudd: '',      currentSort: 'default',          rows: this.props.rows, // I receive the rows data on props               };    }  onSortChange = index => {    const sortMap = {      default: 'up',      up: 'down',      down: 'default',    };    const { currentSort, currentIndex } = this.state;    const nextSort = currentIndex === index ? sortMap[currentSort] : 'default';    const newRows = [...this.state.rows]; // line 40 - here is the error    switch (nextSort) {      case 'up':        newRows.sort((a, b) => (a.cells[index] <= b.cells[index] ? -1 : 1));        break;      case 'down':        newRows.sort((a, b) => (b.cells[index] <= a.cells[index] ? -1 : 1));        break;    }    this.setState({      rows: newRows,      currentSort: nextSort,      currentIndex: index,    });  };...}我认为代码看起来正确,但我收到一条 es-lint 错误消息: Line 40:25:  Use callback in setState when referencing the previous state  react/no-access-state-in-setstate它应该完成一个回调函数,但我不知道如何让它工作。有任何想法吗?
查看完整描述

3 回答

?
慕桂英546537

TA贡献1848条经验 获得超10个赞

您需要使用带有回调函数的 setState 来进行数据处理并为您设置新状态。


这是您案例的转换版本:


  onSortChange = index => {

     const sortMap = {

      default: 'up',

      up: 'down',

      down: 'default',

  };


  this.setState(({ rows, currentIndex, currentSort }) => {


    const nextSort = currentIndex === index ? sortMap[currentSort] : 'default';


     const newRows = [...rows];


      switch (nextSort) {

       case 'up':

       newRows.sort((a, b) => (a.cells[index] <= b.cells[index] ? -1 : 1));

       break;

      case 'down':

      newRows.sort((a, b) => (b.cells[index] <= a.cells[index] ? -1 : 1));

      break;

      default: break;

      }


      return {

        rows: newRows,

        currentSort: nextSort,

        currentIndex: index,

      };

  });


  }


查看完整回答
反对 回复 2022-12-22
?
撒科打诨

TA贡献1934条经验 获得超2个赞

再见,你可以尝试这样的方法:


orderRows = (data, index, nextSort) => {

    switch (nextSort) {

      case 'up':

        data.sort((a, b) => (a.cells[index] <= b.cells[index] ? -1 : 1));

        break;

      case 'down':

        data.sort((a, b) => (b.cells[index] <= a.cells[index] ? -1 : 1));

        break;

    }

    return data;

}


onSortChange = index => {

    const sortMap = {

      default: 'up',

      up: 'down',

      down: 'default',

    };


    const { currentSort, currentIndex } = this.state;


    const nextSort = currentIndex === index ? sortMap[currentSort] : 'default';


    this.setState((prevState) => ({

      rows: this.orderRows(prevState.rows, index, nextSort),

      currentSort: nextSort,

      currentIndex: index,

    }));

  };


查看完整回答
反对 回复 2022-12-22
?
阿波罗的战车

TA贡献1862条经验 获得超6个赞

将道具分配给状态并从那里使用它们是一种 React 反模式(您可以在此处阅读更多相关信息)。


当您尝试实现的场景需要时,推荐的方法是创建一个完全受控的组件,或者在这种情况下,一个部分受控的组件,其中不仅rows从道具中使用,而且对它们的任何转换也通过道具(在本例中为排序)。


下面的代码片段演示了手头问题的简化版本。我们创建一个Parent存储rows其状态的组件,并提供一个执行排序的方法。然后它呈现一个完全受控的Child组件,该组件不需要有自己的状态,而是接收行及其排序器函数作为 props。


该sortRows方法说明了如何使用setState回调,与提供状态对象相比,回调提供了在状态上产生更一致的结果的好处。


class Child extends React.PureComponent {

    render() {

        const { rows, sortRows } = this.props;

        return (

            <div>

                <ul>{ rows.map((row, i) => (<li key={ i }>{ row }</li>)) }</ul>

                <button onClick={ () => { sortRows(true) }}>Sort Ascending</button>

                <button onClick={ () => { sortRows(false) }}>Sort Descending</button>

            </div>

        );

    }

}

class Parent extends React.PureComponent {

    constructor(props) {

        super(props);

        this.state = {

            rows: ['Mercury', 'Venus', 'Earth', 'Mars', 'Jupiter']

        };

    }


    sortRows = (isSortAscending) => {

        this.setState((prevState) => ({

            rows: prevState.rows.slice().sort((a, b) => {

                if (a < b) return -(isSortAscending ? 1 : -1);

                if (a > b) return (isSortAscending ? 1 : -1);

                return 0;

            })

        }));

    }


    render() {

        return <Child rows={ this.state.rows } sortRows={ this.sortRows } />;

    }

}

ReactDOM.render(<Parent />, document.getElementById('root'));

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

<div id="root"></div>


查看完整回答
反对 回复 2022-12-22
  • 3 回答
  • 0 关注
  • 180 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信