【问题标题】:Can I mutate state passed to setState function?我可以改变传递给 setState 函数的状态吗?
【发布时间】:2017-09-04 10:48:16
【问题描述】:

我知道我不应该直接在 React 中改变状态,但是当我使用函数时的情况如何:

onSocialClick = e => {
    const id = e.target.value;
    this.setState((prevState, props) => {
        prevState[id] = !(prevState[id]);
        return prevState;
    });
};

修改传递的对象会不会出错?

编辑:

事实证明,我们大多数人都错了。立即回复docs state it clearly

state 是对应用更改时的组件状态的引用。它不应该直接突变。相反,应该通过基于 state 和 props 的输入构建一个新对象来表示更改

感谢@Tomáš Hübelbauer 在评论中指出这一点。

【问题讨论】:

  • 这不是错误:) 不直接修改状态意味着你应该使用setState,而不是this.state =...。如果你这样做 - 一切都很好,无论你使用什么作为传入参数。
  • @Tomasz 我问了一个后续问题,因为我对您的代码 sn-p 有疑问。你可能会觉得这很有趣:stackoverflow.com/q/47339643/2715716
  • @TomášHübelbauer 谢谢!我已经进行了编辑。
  • 我试图在文档中找到确切的声明,但看起来他们重命名了变量 - prevState 现在只是 state

标签: reactjs setstate


【解决方案1】:

不,您不应该在 setState 的 updater 函数中改变 prevState。

更新函数必须是纯函数


更新函数被调用两次。看到这个discussion

检查以下 codesandbox 并打开代码框的控制台以查看它的运行情况。

【讨论】:

    【解决方案2】:

    更简洁的方法是直接引用您要编辑的属性:

    doIt = () => this.setState(({ [id]: prevValue }) => ({
      [id]: !prevValue,
    }));
    

    【讨论】:

    • 如果[id] 不是state 的直系子代,而是向下一层,是否可以这样做?就我而言,我有一组 [id]s,所有其他 Q/A 和文章都建议复制,但我发现您的解决方案更清晰。
    • @Al.G.您可能必须使用find 来获取正确的索引来访问正确的数组元素
    【解决方案3】:

    你这样做的方式没有错。修改参数然后返回它是完全可以的。但是,当您根据 prevState 的值修改状态时,使用带有 prevState 参数的 setState,它完全适合您的场景,并且处理它的更简洁的方法是

    onSocialClick = e => {
        const id = e.target.value;
        this.setState((prevState, props) => {
            return {[id] : !(prevState[id])};
        });
    };
    

    【讨论】:

      【解决方案4】:

      强烈建议不要直接改变状态。此外,您正在改变先前的状态,然后返回它,这没有多大意义。如果您只想在state[id] 处切换状态,则将您的代码修复为更像:

      onSocialClick = e => {
          const id = e.target.value;
          this.setState({this.state[id]: !this.state[id});
      };
      

      【讨论】:

      • 不鼓励这样做,您应该使用 OP 使用的功能方式(但可能直接使用感兴趣的道具。
      猜你喜欢
      • 1970-01-01
      • 2023-02-10
      • 1970-01-01
      • 2021-10-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多