【问题标题】:ESLint: Use callback in setState when referencing the previous stateESLint:在引用前一个状态时在 setState 中使用回调
【发布时间】:2019-09-25 06:17:09
【问题描述】:

对于这段代码,我收到 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);
  }

【问题讨论】:

  • 您的问题的预期结果是什么?您只想知道为什么会收到此错误消息?
  • 您可以从setState 中删除...this.state。它只会在你改变的状态下更新参数。

标签: javascript reactjs eslint


【解决方案1】:

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

您可以在React documentation 中看到setState(stateChange) 将stateChange 浅合并到状态中。

Object.assign(
  previousState,
  stateChange,
  ...
)

这意味着你不需要传递你以前的状态,除非新的属性依赖它,因为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);
  }

【讨论】:

    【解决方案2】:

    正如您在documentation 中看到的那样

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

    function increment() {
      this.setState({value: this.state.value + 1});
    }
    

    如果这两个 setState 操作在一个批次中组合在一起,假设值为 1,它将如下所示:

    setState({value: 1 + 1})
    setState({value: 1 + 1})
    

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

    function increment() {
      this.setState(prevState => ({value: prevState.value + 1}));
    }
    

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

    在你的情况下,你应该做的是

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

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

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

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

      • 为什么这里需要...previousState
      • 对,完全可以省略 - 这也消除了回调的需要。 ?
      猜你喜欢
      • 2020-11-27
      • 2020-11-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-16
      • 2019-08-04
      • 1970-01-01
      相关资源
      最近更新 更多