ESLint:在引用前一个状态时在 setState 中使用回调

dre*_*val 4 javascript reactjs eslint

对于这段代码,我收到 eslint(AirBnb config) 错误:引用前一个状态时在 setState 中使用回调

此错误是否会以某种方式影响性能以及如何解决?

  handleSelect(event) {
    const entry = event.nativeEvent;

    if (entry == null) {
      this.setState({ ...this.state, selectedEntry: entry });
    } else
      this.setState({
        ...this.state,
        selectedEntry: JSON.stringify(entry),
        markerIsEnabled: true
      });

    console.log(event.nativeEvent);
  }
Run Code Online (Sandbox Code Playgroud)

Ven*_*sky 8

正如您在文档中看到的

此规则应防止在 setState 调用中使用 this.state。当批量调用两个状态调用并因此引用旧状态而不是当前状态时,这样使用 this.state 可能会导致错误。增量函数就是一个例子:

function increment() {
  this.setState({value: this.state.value + 1});
}
Run Code Online (Sandbox Code Playgroud)

如果这两个 setState 操作在一个批处理中组合在一起,则其看起来将类似于以下内容(假定值为 1):

setState({value: 1 + 1})
setState({value: 1 + 1})
Run Code Online (Sandbox Code Playgroud)

通过使用将先前状态作为第一个参数的回调可以避免这种情况:

function increment() {
  this.setState(prevState => ({value: prevState.value + 1}));
}
Run Code Online (Sandbox Code Playgroud)

这就是为什么你有这个规则,以避免像这个例子这样的错误。

对于你的情况,你应该做的是

handleSelect({ nativeEvent }) {    
    if (nativeEvent == null) {
        this.setState(previousState => ({
            ...previousState, 
            selectedEntry: nativeEvent
        }));
    } else {
      this.setState(previousState => ({
        ...previousState,
        selectedEntry: JSON.stringify(entry),
        markerIsEnabled: true
      }));
    }
}
Run Code Online (Sandbox Code Playgroud)

但对于您的情况,不会发生此错误,因为您没有两个连续的错误setState,并且...this.state...prevState不会产生任何差异,因为您没有使用以前的状态来设置新状态。

因此,对于您在问题中提供的代码,只需删除...this.state它即可正常工作,不会出现错误。


Cam*_*ner 5

您可以从中删除...this.statesetState因为它只会更新您已更改的状态中的参数。

您可以在React 文档中看到,setState(stateChange)执行将 stateChange 浅合并到状态中。

Object.assign(
  previousState,
  stateChange,
  ...
)
Run Code Online (Sandbox Code Playgroud)

这意味着你不需要传递你以前的状态,除非新的属性依赖它,因为它setState会为你做这个合并。

handleSelect(event) {
    const entry = event.nativeEvent;

    if (entry == null) {
      this.setState({ selectedEntry: entry });
    } else {
      this.setState({
        selectedEntry: JSON.stringify(entry),
        markerIsEnabled: true
      });
    }

    console.log(event.nativeEvent);
  }
Run Code Online (Sandbox Code Playgroud)


san*_*oco 2

尝试这个。这是因为setState是异步的。

handleSelect({ nativeEvent }) {

    if (nativeEvent == null) {
        this.setState((previousState) => ({
            ...previousState, selectedEntry: nativeEvent
        }));
    } else
      this.setState((previousState) => ({
        ...previousState,
        selectedEntry: JSON.stringify(entry),
        markerIsEnabled: true
      }));
  }
Run Code Online (Sandbox Code Playgroud)