最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - ESLint: Use callback in setState when referencing the previous state - Stack Overflow

programmeradmin1浏览0评论

For this piece of code I am getting eslint(AirBnb config) error: Use callback in setState when referencing the previous state

Does this error influence performance somehow and how can it be solved?

  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);
  }

For this piece of code I am getting eslint(AirBnb config) error: Use callback in setState when referencing the previous state

Does this error influence performance somehow and how can it be solved?

  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);
  }
Share Improve this question asked May 7, 2019 at 14:38 lechamlecham 2,4648 gold badges25 silver badges44 bronze badges 3
  • What is the expected result of your question? You only want to know why you get this error message? – Vencovsky Commented May 7, 2019 at 14:41
  • Possible duplicate of this.state inside setState ReactJS – Anurag Srivastava Commented May 7, 2019 at 14:42
  • 2 You can remove ...this.state from setState. It will only update parameters in the state you have changed. – Cameron Downer Commented May 7, 2019 at 14:43
Add a comment  | 

3 Answers 3

Reset to default 8

As you can see in documentation

This rule should prevent usage of this.state inside setState calls. Such usage of this.state might result in errors when two state calls are called in batch and thus referencing old state and not the current state. An example can be an increment function:

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

If these two setState operations is grouped together in a batch it will look be something like the following, given that value is 1:

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

This can be avoided with using callbacks which takes the previous state as first argument:

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

So this is why you have that rule, to avoid erros like this example.

In your case, what you should do is

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

But for your case, this an error won't happen because you don't have two consecutives setState and also, ...this.state or ...prevState won't make any diference because you aren't using the previous state to set a new state.

So for the code you provided in your question, just remove ...this.state and it will work fine, with no errors.

You can remove ...this.state from setState because it will only update parameters in the state you have changed.

You can see in the React documentation that setState(stateChange) performs a performs a shallow merge of stateChange into the state.

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

This means you don't need to be passing your previous state in, unless new properties depend on it, as setState will do this merge for you.

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);
  }

Try this. It's because setState is async.

handleSelect({ nativeEvent }) {

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

评论列表(0)

  1. 暂无评论