为什么我不能直接修改组件的状态,真的吗? [英] Why can't I directly modify a component's state, really?

查看:104
本文介绍了为什么我不能直接修改组件的状态,真的吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我理解React教程和文档警告没有不确定的条款该状态不应该直接变异,并且所有内容都应该通过 setState

I understand that React tutorials and documentation warn in no uncertain terms that state should not be directly mutated and that everything should go through setState.

我想明白为什么,我不能直接改变状态然后(在同一个函数中)调用 this.setState({})只是为了触发渲染

I would like to understand why, exactly, I can't just directly change state and then (in the same function) call this.setState({}) just to trigger the render.

例如:以下代码似乎工作得很好:

E.g.: The below code seems to work just fine:

const React = require('react');

const App = React.createClass({
    getInitialState: function() {
        return {
            some: {
                rather: {
                    deeply: {
                        embedded: {
                            stuff: 1
                        }}}}};
    },
    updateCounter: function () {
        this.state.some.rather.deeply.embedded.stuff++;
        this.setState({}); // just to trigger the render ...
    },
    render: function() {
        return (
                <div>
                Counter value: {this.state.some.rather.deeply.embedded.stuff}
                <br></br>
                <button onClick={this.updateCounter}>inc</button>
                </div>
        );
    }
});

export default App;

我完全遵循以下惯例,但我希望进一步了解ReactJS的实际工作方式和可能出现什么问题或者使用上面的代码是不是最优的。

I am all for following conventions but I would like to enhance my further understanding of how ReactJS actually works and what can go wrong or is it sub-optimal with the above code.

this.setState 文档基本上确定了两个陷阱:

The notes under the this.setState documentation basically identify two gotchas:


  1. 如果直接改变状态然后调用 this.setState 这可能会替换(覆盖?)突变你做了我不知道在上面的代码中会发生这种情况。

  2. 那个 setState 可能会改变这个。 state 以异步/延迟方式有效,因此在调用 this.setState this.state c $ c>您无法保证能够访问最终的变异状态。我知道,如果 this.setState 是更新函数的最后一次调用,这不是问题。

  1. That if you mutate state directly and then subsequently call this.setState this may replace (overwrite?) the mutation you made. I don't see how this can happen in the above code.
  2. That setState may mutate this.state effectively in an asynchronous / deferred way and so when accessing this.state right after calling this.setState you are not guaranteed to access the final mutated state. I get that, by this is not an issue if this.setState is the last call of the update function.


推荐答案

setState 的React文档可以这样说:

The React docs for setState have this to say:


从不直接改变 this.state ,因为之后调用 setState()可能会取代你做的变异。将 this.state 视为不可变。

NEVER mutate this.state directly, as calling setState() afterwards may replace the mutation you made. Treat this.state as if it were immutable.

setState()不会立即改变 this.state ,但会创建挂起状态转换。调用此方法后访问 this.state 可能会返回现有值。

setState() does not immediately mutate this.state but creates a pending state transition. Accessing this.state after calling this method can potentially return the existing value.

无法保证同步操作调用 setState 并且可以对调用进行批处理以获得性能提升。

There is no guarantee of synchronous operation of calls to setState and calls may be batched for performance gains.

setState()除非条件渲染逻辑在 shouldComponentUpdate()中实现,否则将始终触发重新渲染。如果正在使用可变对象并且逻辑无法在 shouldComponentUpdate()中实现,则仅在以下情况下调用 setState()新状态与以前的状态不同,将避免不必要的重新渲染。

setState() will always trigger a re-render unless conditional rendering logic is implemented in shouldComponentUpdate(). If mutable objects are being used and the logic cannot be implemented in shouldComponentUpdate(), calling setState() only when the new state differs from the previous state will avoid unnecessary re-renders.

基本上,如果你修改这个。状态直接,您创建的情况可能会覆盖这些修改。

Basically, if you modify this.state directly, you create a situation where those modifications might get overwritten.

与您的扩展问题相关1)和2), setState()不是立即的。 它根据其认为正在进行的操作将状态转换排队,其中可能不包括对 this.state 的直接更改。因为它排队而不是立即应用,所以完全有可能在两者之间修改某些内容,直到您的直接更改被覆盖。

Related to your extended questions 1) and 2), setState() is not immediate. It queues a state transition based on what it thinks is going on which may not include the direct changes to this.state. Since it's queued rather than applied immediately, it's entirely possible that something is modified in between such that your direct changes get overwritten.

如果没有别的,你可能会更好考虑到不直接修改 this.state 可以被视为良好做法。您可能会亲自知道您的代码与React交互的方式是这些覆盖或其他问题不会发生,但您正在创建一种情况,其他开发人员或未来的更新可能突然发现自己有奇怪或微妙的问题。

If nothing else, you might be better off just considering that not directly modifying this.state can be seen as good practice. You may know personally that your code interacts with React in such a way that these over-writes or other issues can't happen but you're creating a situation where other developers or future updates can suddenly find themselves with weird or subtle issues.

这篇关于为什么我不能直接修改组件的状态,真的吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆