web-dev-qa-db-fra.com

Comment obtenir une distribution simple depuis this.props en utilisant connect with / Redux?

J'ai un simple composant React que je connecte (mappage d'un tableau/état simple). Pour éviter de faire référence au contexte de magasin, je voudrais un moyen d'obtenir "l'envoi" directement à partir des accessoires. J'ai vu d'autres personnes utiliser cette approche, mais n'y ai pas accès pour une raison quelconque :)

Voici les versions de chaque dépendance npm que j'utilise actuellement

"react": "0.14.3",
"react-redux": "^4.0.0",
"react-router": "1.0.1",
"redux": "^3.0.4",
"redux-thunk": "^1.0.2"

Voici le composant avec la méthode connect

class Users extends React.Component {
    render() {
        const { people } = this.props;
        return (
            <div>
                <div>{this.props.children}</div>
                <button onClick={() => { this.props.dispatch({type: ActionTypes.ADD_USER, id: 4}); }}>Add User</button>
            </div>
        );
    }
};

function mapStateToProps(state) {
    return { people: state.people };
}

export default connect(mapStateToProps, {
    fetchUsers
})(Users);

Si vous avez besoin de voir le réducteur (rien d’excitant mais le voilà)

const initialState = {
    people: []
};

export default function(state=initialState, action) {
    if (action.type === ActionTypes.ADD_USER) {
        let newPeople = state.people.concat([{id: action.id, name: 'wat'}]);
        return {people: newPeople};
    }
    return state;
};

Si vous avez besoin de voir comment mon routeur est configuré avec redux

const createStoreWithMiddleware = applyMiddleware(
      thunk
)(createStore);

const store = createStoreWithMiddleware(reducers);

var Route = (
  <Provider store={store}>
    <Router history={createBrowserHistory()}>
      {Routes}
    </Router>
  </Provider>
);

mise à jour

on dirait que si j'omettais ma propre répartition dans la connexion (actuellement, je montre fetchUsers), la répartition est gratuite (je ne suis pas sûr que ce soit comme cela qu'une installation avec des actions asynchrones fonctionnerait normalement). Les gens se mélangent-ils ou est-ce tout ou rien?

[mapDispatchToProps]

100
Toran Billups

Par défaut, mapDispatchToProps est simplement dispatch => ({ dispatch }).
Donc, si vous ne spécifiez pas le deuxième argument de connect(), vous obtiendrez dispatch injecté comme accessoire dans votre composant.

Si vous transmettez une fonction personnalisée à mapDispatchToProps, vous pouvez tout faire avec la fonction.
Quelques exemples:

// inject onClick
function mapDispatchToProps(dispatch) {
  return {
    onClick: () => dispatch(increment())
  };
}

// inject onClick *and* dispatch
function mapDispatchToProps(dispatch) {
  return {
    dispatch,
    onClick: () => dispatch(increment())
  };
}

Pour vous épargner en tapant, Redux fournit bindActionCreators() qui vous permet d'activer ceci:

// injects onPlusClick, onMinusClick
function mapDispatchToProps(dispatch) {
  return {
    onPlusClick: () => dispatch(increment()),
    onMinusClick: () => dispatch(decrement())
  };
}

dans ceci:

import { bindActionCreators } from 'redux';

// injects onPlusClick, onMinusClick
function mapDispatchToProps(dispatch) {
  return bindActionCreators({
    onPlusClick: increment,
    onMinusClick: decrement
  }, dispatch);
}

ou même plus court lorsque les noms d'accessoires correspondent aux noms de créateur d'action:

// injects increment and decrement
function mapDispatchToProps(dispatch) {
  return bindActionCreators({ increment, decrement }, dispatch);
}

Si vous le souhaitez, vous pouvez certainement ajouter dispatch à la main:

// injects increment, decrement, and dispatch itself
function mapDispatchToProps(dispatch) {
  return {
    ...bindActionCreators({ increment, decrement }), // es7 spread syntax
    dispatch
  };
}

Il n'y a pas de conseil officiel pour savoir si vous devriez le faire ou non. connect() sert généralement de limite entre les composants prenant en charge Redux et les composants ne prenant pas en charge Redux. C’est pourquoi nous pensons qu’il n’est pas logique d’injecter les deux créateurs d’actions liées et dispatch. Mais si vous sentez que vous avez besoin de le faire, n'hésitez pas.

Enfin, le modèle que vous utilisez actuellement est un raccourci encore plus court que d'appeler bindActionCreators. Quand tout ce que vous faites est de retourner bindActionCreators, vous pouvez omettre l'appel de manière à éviter cela:

// injects increment and decrement
function mapDispatchToProps(dispatch) {
  return bindActionCreators({ increment, decrement }, dispatch);
}

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

peut être écrit comme ça

export default connect(
  mapStateToProps,
  { increment, decrement } // injects increment and decrement
)(App);

Cependant, vous devrez abandonner cette syntaxe courte de Nice chaque fois que vous voudrez quelque chose de plus personnalisé, comme passer dispatch également.

274
Dan Abramov

Vous pouvez généralement mélanger et assortir en fonction de ce que vous souhaitez.

Vous pouvez passer dispatch comme accessoire si c'est ce que vous voulez:

export default connect(mapStateToProps, (dispatch) => ({
    ...bindActionCreators({fetchUsers}, dispatch), dispatch
}))(Users);

Je ne sais pas comment fetchUsers est utilisé (en tant que fonction asynchrone?), Mais vous utiliseriez généralement quelque chose comme bindActionCreators à auto-bind dispatch et vous ne le feriez pas ne pas utiliser dispatch directement dans les composants connectés.

En utilisant le répertoire dispatch, une sorte de répertoire couple dumb, composant sans état avec redux. Ce qui peut le rendre moins portable.

5
Davin Tryon

Bien que vous puissiez passer dispatch dans le cadre de dispatchToProps, il est conseillé d’éviter d’accéder au store ou dispatch directement à partir de vos composants. Il semblerait que vous feriez mieux de servir un créateur d’actions liées dans le deuxième argument de connect dispatchToProps

Voir un exemple que j'ai posté ici https://stackoverflow.com/a/34455431/2644281 explique comment transmettre un "créateur d'action lié" de cette manière, vos composants n'ont pas besoin de connaître directement la ou dépendent du magasin/envoi.

Désolé d'être bref. Je mettrai à jour w/plus d'infos.

1
Erik Aybar