Quand bindActionCreators serait-il utilisé dans react / redux?

En regardant les documents redux pour bindActionCreators et il indique que:

Le seul cas d’utilisation de bindActionCreators est lorsque vous souhaitez transmettre certains créateurs d’action à un composant qui ne connaît pas Redux, et que vous ne souhaitez pas y transférer dispatch ou le magasin Redux.

Quel serait un exemple où bindActionCreators serait utilisé / nécessaire? Et quel type de composant ne serait pas au courant de Redux?

Quels sont les avantages / inconvénients des deux options?

//actionCreator import * as actionCreators from './actionCreators' function mapStateToProps(state) { return { posts: state.posts, comments: state.comments } } function mapDispatchToProps(dispatch) { return bindActionCreators(actionCreators, dispatch) } 

contre

 function mapStateToProps(state) { return { posts: state.posts, comments: state.comments } } function mapDispatchToProps(dispatch) { return { someCallback: (postId, index) => { dispatch({ type: 'REMOVE_COMMENT', postId, index }) } } } 

99% du temps, il est utilisé avec la fonction React-Redux connect() , dans le cadre du paramètre mapDispatchToProps . Il peut être utilisé explicitement dans la fonction mapDispatch vous fournissez ou automatiquement si vous utilisez la syntaxe abrégée de l’object et transmettez un object rempli de créateurs d’actions à connect .

L’idée est qu’en pré-liant les créateurs d’action, le composant que vous transmettez à connect() ne sait techniquement pas qu’il est connecté – il sait simplement qu’il doit exécuter this.props.someCallback() . D’un autre côté, si vous n’avez pas this.props.dispatch(someActionCreator()) créateurs d’action et appelé this.props.dispatch(someActionCreator()) , le composant “sait” maintenant qu’il est connecté car il s’attend à props.dispatch que props.dispatch existe.

J’ai écrit quelques reflections sur ce sujet dans mon blog Idiomatic Redux: Pourquoi utiliser des créateurs d’action? .

Je ne pense pas que la réponse la plus populaire répond en fait à la question.

Tous les exemples ci-dessous font essentiellement la même chose et suivent le concept «non contraignant».

 // option 1 const mapDispatchToProps = (dispatch) => ({ action: () => dispatch(action()) }) // option 2 const mapDispatchToProps = (dispatch) => ({ action: bindActionCreators(action, dispatch) }) // option 3 const mapDispatchToProps = { action: action } 

L’option n ° 3 n’est qu’un raccourci pour l’option n ° 1, la vraie question est donc de savoir pourquoi utiliser l’option n ° 1 par rapport à l’option n ° 2. Je les ai tous deux utilisés dans le code de réaction-redux, et je trouve que c’est plutôt déroutant.

Je pense que la confusion vient du fait que tous les exemples de doc réact-redux utilisent bindActionCreators tandis que le doc pour bindActionCreators (cité dans la question elle-même) dit de ne pas l’utiliser avec react-redux.

Je suppose que la réponse est la cohérence dans le code, mais je préfère personnellement envelopper les actions de manière explicite lorsque cela est nécessaire.

Exemple plus complet, passez un object plein de créateurs d’actions à connecter:

 import * as ProductActions from './ProductActions'; // component part export function Product({ name, description }) { return 
} // container part function mapStateToProps(state) { return {...state}; } function mapDispatchToProps(dispatch) { return bindActionCreators({ ...ProductActions, }, dispatch); } export default connect(mapStateToProps, mapDispatchToProps)(Product);

Je vais essayer de répondre aux questions originales …

Composants Smart & Dumb

Dans votre première question, vous demandez essentiellement pourquoi bindActionCreators est nécessaire en premier lieu et quels types de composants ne devraient pas connaître Redux.

En bref, l’idée est que les composants doivent être divisés en composants intelligents (conteneur) et stupides (présentationnels). Les composants muets fonctionnent sur la base du besoin de savoir. Leur travail de base est de rendre les données données au HTML et rien de plus. Ils ne devraient pas être au courant du fonctionnement interne de l’application. Ils peuvent être considérés comme la couche frontale de votre application.

D’autre part, les composants intelligents sont une sorte de colle, qui prépare les données pour les composants stupides et ne fait de préférence aucun rendu HTML.

Ce type d’architecture favorise le couplage libre entre la couche d’interface utilisateur et la couche de données située en dessous. Cela permet de remplacer facilement l’une des deux couches par un autre élément (un nouveau design de l’interface utilisateur), qui ne cassera pas l’autre couche.

Pour répondre à votre question: les composants stupides ne devraient pas connaître Redux (ni les détails d’implémentation inutiles de la couche de données), car nous pourrions vouloir le remplacer par quelque chose à l’avenir.

Vous trouverez plus d’informations sur ce concept dans le manuel Redux et plus en détail dans l’article Composants de présentation et de conteneur de Dan Abramov.

Quel exemple est le meilleur

La deuxième question portait sur les avantages / inconvénients des exemples donnés.

Dans le premier exemple, les créateurs d’actions sont définis dans un fichier / module actionCreators distinct, ce qui signifie qu’ils peuvent être réutilisés ailleurs. C’est à peu près la manière standard de définir des actions. Je ne vois aucun inconvénient à cela.

Le second exemple définit des créateurs d’actions en ligne, qui présentent de nombreux inconvénients:

  • les créateurs d’action ne peuvent pas être réutilisés (évidemment)
  • la chose est plus verbeuse, ce qui se traduit par moins lisible
  • les types d’action sont codés en dur – il est préférable de les définir séparément, afin qu’ils puissent être référencés dans les réducteurs – ce qui réduirait les risques de fautes de frappe
  • La définition des créateurs d’actions en ligne est contraire à la manière recommandée / prévue de les utiliser – ce qui rendra votre code un peu moins lisible pour la communauté, au cas où vous envisagez de partager votre code.

Le deuxième exemple a un avantage sur le premier – il est plus rapide d’écrire! Donc, si vous n’avez pas de plus grands plans pour votre code, cela pourrait bien se passer.

J’espère avoir réussi à clarifier les choses un peu …

La déclaration de documents est très claire:

Le seul cas d’utilisation de bindActionCreators est lorsque vous souhaitez transmettre certains créateurs d’action à un composant qui ne connaît pas Redux, et que vous ne souhaitez pas y transmettre dispatch ou le magasin Redux.

Ceci est clairement un cas d’utilisation qui peut survenir dans les conditions suivantes:

Disons que nous avons les composants A et B:

 // A use connect and updates the redux store const A = props => {} export default connect()(A) // B doesn't use connect and doesn't have idea of redux store const B = props => {} export default B 

Injecter pour réagir-redux: (A)

 const boundActionCreators = bindActionCreators(SomeActionCreator, dispatch) // myActionCreatorMethod, // myActionCreatorMethod2, // myActionCreatorMethod3, // when we want to dispatch const action = SomeActionCreator.myActionCreatorMethod('My updates') dispatch(action) 

Injecté par react-redux: (B)

 const { myActionCreatorMethod } = props  

Remarqué de ce qui suit?

  • Nous avons mis à jour le magasin de redux à travers le composant A alors que nous ne connaissions pas le magasin de redux dans le composant B.

  • Nous ne mettons pas à jour le composant A. Pour savoir ce que je veux dire exactement, vous pouvez explorer ce post . J’espère que vous aurez une idée.