2 votes

mapStateToProps doit-il mettre à jour les props de manière asynchrone ?

J'essaie de déterminer si c'est valable de await un appel d'action depuis React lorsque vous devez être en mesure de récupérer la valeur des props immédiatement. En d'autres termes, considérez cet exemple :

// Import the Redux store directly (this is just to show that the store will update synchronously) 
import store from '../store';
const state = store.getState();

// Where foo is an object created by combineReducers and bar is a property of foo with initial value of 'baz'
console.log(this.props.foo.bar); // Prints 'baz'
console.log(state.foo.bar); // Prints 'baz'

// Now, call the action to set bar to 'new value'
this.props.setBar('new value');

console.log(this.props.foo.bar); // Prints 'baz' (still the old value)
console.log(state.foo.bar); // Prints 'new value' (updated)

// Currently, this function call will fail because it finds the old value of bar. This is the point of needing the value immediately... This function will need to look for the updated value of bar in state. I can't pass the new value directly as a parameter, because the function may also need to be called in other situations where it's not readily available like this one.
doSomethingThatWillLookForBar();

C'est le comportement que j'ai observé : l'action est synchrone et le magasin Redux est mis à jour de manière synchrone, mais le composant est mis à jour de manière asynchrone. En observant le débogueur, je peux voir que le prop est correctement mis à jour, donc mapStateToProps fonctionne, mais pas de manière synchrone. Si c'est le cas, ce serait comme setState . Lorsque vous définissez un état, si vous avez immédiatement besoin d'obtenir l'état mis à jour, vous devez soit await le site setState ou utiliser setState Le paramètre de rappel de l'utilisateur. Donc... quand je await mon appel à l'action, cela fonctionne parfaitement :

// Before action call
console.log(this.props.foo.bar); // Prints 'baz'
console.log(state.foo.bar); // Prints 'baz'

// Now, call the action with an await
await this.props.setBar('new value');

console.log(this.props.foo.bar); // Prints 'new value'  (updated)
console.log(state.foo.bar); // Prints 'new value' (updated)

Cela fonctionne donc très bien, mais je ne trouve rien dans la documentation qui confirme qu'il est acceptable de procéder ainsi. Tout ce que je peux trouver suggère que les opérations Redux devraient être entièrement synchrones (à moins d'utiliser un middleware Thunk pour envoyer une action asynchrone). Cela me laisse avec le soupçon que quelque chose ne va pas. Je suppose que mon utilisation est correcte et que cette omission dans la documentation est juste parce que la documentation suppose que vous n'avez généralement pas besoin de tirer immédiatement la valeur que vous définissez à partir de props (puisque vous la définissez, vous devriez déjà l'avoir à portée de main). Donc, j'essaie juste d'avoir la confirmation que c'est un comportement attendu avant de supposer que c'est correct et de passer à autre chose.

À titre de référence, voici l'utilisation que je fais du connect fonction :

const mapStateToProps = state => ({
  foo: state.foo
});

const mapDispatchToProps = dispatch => {
  return {
    setBar: (value) => {
      dispatch(setBar(value))
    }
  }
};

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(Foo);

2voto

markerikson Points 442

L'envoi d'actions met le magasin à jour immédiatement. Cependant, les props des composants React ne seront pas mis à jour immédiatement après, car :

  • Vous êtes toujours au milieu de l'exécution de la boucle d'événement actuelle, donc React n'a pas encore eu l'occasion de rendre à nouveau le composant.
  • En fonction de l'endroit et du moment où l'action a été envoyée, React peut rendre le composant de façon asynchrone, mais pas immédiatement.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X