阻止this.state与setState

时间:2018-10-08 09:17:01

标签: javascript reactjs eslint static-analysis

The reference状态:

  

setState()并不总是立即更新组件。它可能会批量更新或将更新推迟到以后。这使得在调用setState()之后立即读取this.state可能是一个陷阱。而是使用componentDidUpdate或setState回调(setState(updater,callback)),确保在应用更新后均能触发这两种方法。如果需要基于先前的状态来设置状态,请阅读以下有关updater参数的信息。

因此在React中将this.state值与setState一起使用被认为是错误的,因为setState是异步的,可能会导致使用错误的值更新状态({{3 }):

// destructured
const { state, setState } = this;
setState({ foo: state.foo });

// destructured
const { foo } = this.state;
setState({ foo });

// undestructured
this.setState({ foo: this.state.foo });

虽然这是更新状态(demo)的正确方法:

// destructured
this.setState(({ foo }) => ({ foo }));

// undestructured
this.setState(state => ({ foo: state.foo }));

是否存在ESLint规则或其他方法来防止其中某些{\ {1}}被滥用的情况?

我认为可能很难,但可以通过静态分析解决此问题。

2 个答案:

答案 0 :(得分:3)

如果您使用:

// destructured
const { state, setState } = this;
setState({ foo: state.foo });

Eslint仍然由于state.foo(访问对象的属性)而警告您。为了避免这种情况,您可以定义如下:

// destructured
const { state: { foo }, setState } = this;
setState({ foo });

但是,如果您使用:

// undestructured
this.setState({ foo: this.state.foo });

然后,ESLINT将警告您使用诸如以下的解构语法:

const { foo } = this.state
this.setState({foo})

请注意:由于foo是要更新的变量名并且名称匹配,因此我们只能使用{foo}并与{foo: foo}相同。


而且,但是,我更喜欢使用this.setState()语法,而不是解构为this。因为在任何应用程序中,我们都会在必要时使用this。如果在看到const { ... } = this而不是setState时在代码之间看,使用this.setState似乎会造成混淆。从第三位开发者开始思考。


从注释中,您想要一个接一个地更新状态,那么您应该使用回调:

onClick = () => {
   this.setState({ foo: 'Bar' }, () => {
      this.setState({ foo: this.state.foo + '!' });
   });
}

现在,您将可以在演示中看到对Hello Bar!的更改。

如果您这样使用setState:

onClick = () => {
   this.setState({ foo: 'Bar' })
   this.setState({ foo: this.state.foo + '!' });
   // obviously, better to use updater syntax though.
}

然后,第一个setState将被最后一个setState覆盖。然后,您将在演示中对Hello Foo!进行更改。

此外,文档指出相同。 updater语法只是一种方便的方法,但其结果与没有updater语法的结果完全相同。最重要的作用仅在于其回调语法。使用回调语法,以便您可以在更新后的状态立即访问。


了解有关解构语法的更多信息。您可以关注my another post,在这里您可以找到详细的信息和一些熟悉的链接。

答案 1 :(得分:2)

eslint-plugin-react将按照react/no-access-state-in-setstate规则进行检查

  

此规则应防止在setState调用中使用this.state。当批量调用两个状态调用并因此引用旧状态而不是当前状态时,this.state的这种用法可能会导致错误。