我可以改变传递给 setState 函数的状态吗?
Posted
技术标签:
【中文标题】我可以改变传递给 setState 函数的状态吗?【英文标题】:Can I mutate state passed to setState function? 【发布时间】: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 有疑问。你可能会觉得这很有趣:***.com/q/47339643/2715716
@TomášHübelbauer 谢谢!我已经进行了编辑。
我试图在文档中找到确切的声明,但看起来他们重命名了变量 - prevState
现在只是 state
【参考方案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 使用的功能方式(但可能直接使用感兴趣的道具。以上是关于我可以改变传递给 setState 函数的状态吗?的主要内容,如果未能解决你的问题,请参考以下文章