1
votes

Est-il acceptable d'appeler setState dans le rappel à setState?

J'ai le code suivant:

handleBlur = event => {
    const name = event.target.name;
    const value = event.target.value;
    this.setState({
        [name]: value
    }, () => {
        validateInput(this.state, name).then((errors) => {
            this.setState({
                errors: errors
            })
        })
    });
}

Lors du déclenchement de l'événement, j'ai défini le nom d'utilisateur / mot de passe dans l'état du composant. Dans le rappel, je valide que tous les champs répondent à mes critères et renvoie toutes les erreurs rencontrées. Je lance ensuite à nouveau setState pour mettre ces erreurs en état. Ma question est la suivante: y a-t-il une meilleure façon de faire cela? Il ne semble pas du tout pratique d'avoir setState dans un setState.


0 commentaires

4 Réponses :


0
votes

Je pense que vous ne devriez pas définir de valeurs dans handleBlur, mais plutôt définir des valeurs dans handleChange et valider et définir les erreurs, le cas échéant, dans votre gestionnaire d'événements handleBlur. Si vous le souhaitez, vous devez toujours définir des valeurs et des erreurs dans un seul setState au lieu de faire deux appels.


1 commentaires

Oh ouais, c'est un bon point. Je n'ai pas envisagé d'utiliser à la fois onChange et onBlur. Merci.



0
votes

Vous pouvez utiliser componentDidUpdate pour mettre à jour les erreurs

handleBlur = event => {
  const name = event.target.name
  const value = event.target.value
  this.setState({ [name]: value })
}

componentDidUpdate  (prevProps, prevState)  {
  if (prevState[name] !== this.state[name])
   validateInput(this.state, name).then(errors => {
     this.setState({ errors: errors })
   })
}


0 commentaires

3
votes

Si c'est pour la validation, je pense que vous devriez utiliser setState dans un rappel car il rendra les composants plusieurs fois.

Vous pouvez supprimer le rappel en définissant le nom et erreurs dans un seul setState.

const validateInput = (state, inputName, inputValue) => {
  const errors = { ...state.errors };

  if (/* condition */) {
    errors[inputName] = /* error's value */;
  }

  return errors;
}

handleBlur = event => {
    const name = event.target.name;
    const value = event.target.value;

    this.setState({
        [name]: value,
        errors: validateInput(this.state, name, value),
    });
}

J'espère que cela vous aidera!


1 commentaires

Cela fonctionne parfaitement - Le seul souci que j'ai est validateInput est une fonction asynchrone, donc elle renvoie une promesse - Et il le faut, car elle a un appel API. Je pense que je vais traiter de la validation dans ComponentDidUpdate, comme suggéré ci-dessus.



0
votes

Pour commencer, déplacez simplement la validation comme ceci:

handleBlur = event => {
  const name = event.target.name;
  const value = event.target.value;
  this.setState({ [name]: value });
  validateInput(name, value)
    .then((errors) => this.setState({ errors }));
}


1 commentaires

validateInput prend cependant l'état actuel. Puisque setState est synchronisé, il se peut qu'il ne me fournisse pas les données correctes, sauf s'il s'agit du rappel.