3
votes

ESLint: utiliser le rappel dans setState lors du référencement de l'état précédent

Pour ce morceau de code, je reçois une erreur eslint (configuration AirBnb): Utiliser le rappel dans setState lors du référencement de l'état précédent

Cette erreur influence-t-elle d'une manière ou d'une autre les performances et comment peut-elle être résolue?

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


3 commentaires

Quel est le résultat attendu de votre question? Vous voulez seulement savoir pourquoi vous recevez ce message d'erreur?


Copie possible de this.state dans setState ReactJS


Vous pouvez supprimer ... this.state de setState . Il ne mettra à jour les paramètres que dans l'état que vous avez modifié.


3 Réponses :


2
votes

Essayez ceci. C'est parce que setState est asynchrone.

handleSelect({ nativeEvent }) {

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


2 commentaires

pourquoi ... previousState est-il nécessaire ici du tout?


Bien, pourrait être omis du tout - ce qui supprime également la nécessité d'un rappel. 🙄



3
votes

Comme vous pouvez le voir dans documentation

Cette règle devrait empêcher l'utilisation de this.state dans les appels setState. Une telle utilisation de this.state peut entraîner des erreurs lorsque deux appels d'état sont appelés par lots et référencent ainsi l'ancien état et non l'état actuel. Un exemple peut être une fonction d'incrémentation:

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

Si ces deux opérations setState sont regroupées dans un lot, cela ressemblera à ceci, étant donné que la valeur est 1:

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

Cela peut être évité en utilisant des callbacks qui prennent l'état précédent comme premier argument:

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

C'est pourquoi vous avez cette règle, pour éviter les erreurs comme cet exemple.

Dans votre cas, ce que vous devez faire est

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


0 commentaires

4
votes

Vous pouvez supprimer ... this.state de setState car il ne mettra à jour les paramètres que dans l'état que vous avez changé.

Vous pouvez voir dans le React documentation que setState (stateChange) effectue une fusion superficielle de stateChange dans l'état.

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

Cela signifie que vous n'avez pas besoin de passer votre état précédent, à moins que de nouvelles propriétés en dépendent, comme setState effectuera cette fusion pour vous.

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


0 commentaires