繁体   English   中英

为什么我在使用 React useReducer 时不能返回之前 state 的 map

[英]Why can't I return map of previous state when using React useReducer

我创建了一个简单的应用程序来说明:

在应用程序中,我使用减速器来保留 state 和复选框数组以及 allChecked boolean

{
  checks: [
    { id: 1, selected: false },
    { id: 2, selected: false },
    { id: 3, selected: false },
  ],
  allChecked: false,
}

我有一个减速器,当一个复选框被更改时,应该在检查数组中识别该复选框并将值设置为与原来相反的值

  case 'SELECT_CHECK': {
    return {
      checks: state.checks.map((check, i) => {
        if (action.id === check.id) {
          check.selected = !check.selected;
        }
        return check;
      }),
      allChecked: state.checks.reduce((acc, check) => {
        if (!acc) return false;
        return check.selected;
      }, true),
    };
  }

单击每个复选框时,map 应该运行并返回check.selected =.check.selected 将其记录下来表明它按预期工作,但重新调整此 state 永远不会更改 state。 并且复选框永远不会被选中。

我找到了一个解决方法,它通过调度操作将复选框的 state 传递给e.target.checked

  //checkbox jsx
  <input
    type='checkbox'
    checked={check.selected}
    onChange={(e) => {
      dispatch({ type: 'SELECT_CHECK', id: check.id, checked: e.target.checked });
    }}
  />
  //reducer case statement
  case 'SELECT_CHECK': {
    return {
      checks: state.checks.map((check, i) => {
        if (action.id === check.id) {
          check.selected = action.checked;
        }
        return check;
      }),
      allChecked: state.checks.reduce((acc, check) => {
        if (!acc) return false;
        return check.selected;
      }, true),
    };
  }

虽然这个功能我想了解为什么最初的尝试不起作用,以及是否有办法让这个 function 没有传递action.checked值。

这是一个 GIF,显示预期的 State Select 所有复选框演示

When you need to update an object in React state, you should always replace the existing object in state with the new object instead of mutating the object in state. 这个:

  checks: state.checks.map((check, i) => {
    if (action.id === check.id) {
      check.selected = !check.selected;
    }
    return check;
  }),

应该

  checks: state.checks.map(check => (
    action.id === check.id ? ({ ...check, selected: !check.selected }) : check
  ))

{ ...check, selected: !check.selected }

创建一个新的 object,它具有 state 中现有 object 的所有属性,但反向selected的属性除外。

相比之下,您的

check.selected = !check.selected;

mutates the object without returning a new one, and in such a case - if the object in the previous state and the object in the new state are === - React may try to completely skip the re-rendering involving that object, because it未检测到 state 差异。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM