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

我正在对一个表进行排序,它应该按字母顺序对列进行排序,按字母顺序反转并在每次调用该方法时返回到原始形式。


这是我的代码:


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

它应该完成一个回调函数,但我不知道如何让它工作。

有任何想法吗?



月关宝盒
浏览 181回答 3
3回答

慕桂英546537

您需要使用带有回调函数的 setState 来进行数据处理并为您设置新状态。这是您案例的转换版本:&nbsp; onSortChange = index => {&nbsp; &nbsp; &nbsp;const sortMap = {&nbsp; &nbsp; &nbsp; default: 'up',&nbsp; &nbsp; &nbsp; up: 'down',&nbsp; &nbsp; &nbsp; down: 'default',&nbsp; };&nbsp; this.setState(({ rows, currentIndex, currentSort }) => {&nbsp; &nbsp; const nextSort = currentIndex === index ? sortMap[currentSort] : 'default';&nbsp; &nbsp; &nbsp;const newRows = [...rows];&nbsp; &nbsp; &nbsp; switch (nextSort) {&nbsp; &nbsp; &nbsp; &nbsp;case 'up':&nbsp; &nbsp; &nbsp; &nbsp;newRows.sort((a, b) => (a.cells[index] <= b.cells[index] ? -1 : 1));&nbsp; &nbsp; &nbsp; &nbsp;break;&nbsp; &nbsp; &nbsp; case 'down':&nbsp; &nbsp; &nbsp; newRows.sort((a, b) => (b.cells[index] <= a.cells[index] ? -1 : 1));&nbsp; &nbsp; &nbsp; break;&nbsp; &nbsp; &nbsp; default: break;&nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; return {&nbsp; &nbsp; &nbsp; &nbsp; rows: newRows,&nbsp; &nbsp; &nbsp; &nbsp; currentSort: nextSort,&nbsp; &nbsp; &nbsp; &nbsp; currentIndex: index,&nbsp; &nbsp; &nbsp; };&nbsp; });&nbsp; }

撒科打诨

再见,你可以尝试这样的方法:orderRows = (data, index, nextSort) => {&nbsp; &nbsp; switch (nextSort) {&nbsp; &nbsp; &nbsp; case 'up':&nbsp; &nbsp; &nbsp; &nbsp; data.sort((a, b) => (a.cells[index] <= b.cells[index] ? -1 : 1));&nbsp; &nbsp; &nbsp; &nbsp; break;&nbsp; &nbsp; &nbsp; case 'down':&nbsp; &nbsp; &nbsp; &nbsp; data.sort((a, b) => (b.cells[index] <= a.cells[index] ? -1 : 1));&nbsp; &nbsp; &nbsp; &nbsp; break;&nbsp; &nbsp; }&nbsp; &nbsp; return data;}onSortChange = index => {&nbsp; &nbsp; const sortMap = {&nbsp; &nbsp; &nbsp; default: 'up',&nbsp; &nbsp; &nbsp; up: 'down',&nbsp; &nbsp; &nbsp; down: 'default',&nbsp; &nbsp; };&nbsp; &nbsp; const { currentSort, currentIndex } = this.state;&nbsp; &nbsp; const nextSort = currentIndex === index ? sortMap[currentSort] : 'default';&nbsp; &nbsp; this.setState((prevState) => ({&nbsp; &nbsp; &nbsp; rows: this.orderRows(prevState.rows, index, nextSort),&nbsp; &nbsp; &nbsp; currentSort: nextSort,&nbsp; &nbsp; &nbsp; currentIndex: index,&nbsp; &nbsp; }));&nbsp; };

阿波罗的战车

将道具分配给状态并从那里使用它们是一种 React 反模式(您可以在此处阅读更多相关信息)。当您尝试实现的场景需要时,推荐的方法是创建一个完全受控的组件,或者在这种情况下,一个部分受控的组件,其中不仅rows从道具中使用,而且对它们的任何转换也通过道具(在本例中为排序)。下面的代码片段演示了手头问题的简化版本。我们创建一个Parent存储rows其状态的组件,并提供一个执行排序的方法。然后它呈现一个完全受控的Child组件,该组件不需要有自己的状态,而是接收行及其排序器函数作为 props。该sortRows方法说明了如何使用setState回调,与提供状态对象相比,回调提供了在状态上产生更一致的结果的好处。class Child extends React.PureComponent {&nbsp; &nbsp; render() {&nbsp; &nbsp; &nbsp; &nbsp; const { rows, sortRows } = this.props;&nbsp; &nbsp; &nbsp; &nbsp; return (&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <ul>{ rows.map((row, i) => (<li key={ i }>{ row }</li>)) }</ul>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <button onClick={ () => { sortRows(true) }}>Sort Ascending</button>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <button onClick={ () => { sortRows(false) }}>Sort Descending</button>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </div>&nbsp; &nbsp; &nbsp; &nbsp; );&nbsp; &nbsp; }}class Parent extends React.PureComponent {&nbsp; &nbsp; constructor(props) {&nbsp; &nbsp; &nbsp; &nbsp; super(props);&nbsp; &nbsp; &nbsp; &nbsp; this.state = {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; rows: ['Mercury', 'Venus', 'Earth', 'Mars', 'Jupiter']&nbsp; &nbsp; &nbsp; &nbsp; };&nbsp; &nbsp; }&nbsp; &nbsp; sortRows = (isSortAscending) => {&nbsp; &nbsp; &nbsp; &nbsp; this.setState((prevState) => ({&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; rows: prevState.rows.slice().sort((a, b) => {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (a < b) return -(isSortAscending ? 1 : -1);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (a > b) return (isSortAscending ? 1 : -1);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return 0;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; })&nbsp; &nbsp; &nbsp; &nbsp; }));&nbsp; &nbsp; }&nbsp; &nbsp; render() {&nbsp; &nbsp; &nbsp; &nbsp; return <Child rows={ this.state.rows } sortRows={ this.sortRows } />;&nbsp; &nbsp; }}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>
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript