Redux: Vous appelez store.dispatch () depuis un fichier de composant React?

Créé le 19 oct. 2015  ·  10Commentaires  ·  Source: reduxjs/redux

Je m'excuse si c'est quelque chose qui a déjà été clarifié, mais une recherche par mot-clé dans les problèmes n'a rien trouvé qui ait aidé.

Si je veux appeler store.dispatch(someAction) partir d'un fichier de composant, quelle est la manière correcte d'accéder à l'instance store ?

Pour le moment, j'ai ce qui suit, qui fonctionne, mais je ne suis pas sûr que ce soit la bonne approche:

index.jsx:

...
const store = applyMiddleware(
  loggingMiddleware, // log every action
  thunk // making API requests from actions
)(createStore)(reducer);

export {
  store
};
...

Controls.jsx

import {store} from './index.jsx';
import * as actions from './actions';
...
let clickHandler = function(node, data) {
  store.dispatch(actions.nodeClicked(data))
}
export const Controls = React.createClass({
  render: function() {
    // React component gets rendered, and it passes the clickHandler to a 
    // function that attaches it to a D3 visualization
  }
});

Y a-t-il quelque chose de mal à exporter / importer le magasin comme celui-ci? Je pense que je pourrais simplement créer les gestionnaires de clics dans le cadre du composant React et appeler this.context.store , mais en réalité, il y a environ une douzaine de gestionnaires d'événements différents qui sont passés à la visualisation D3, donc ce n'est pas vraiment pratique dans ce domaine. situation.

question

Commentaire le plus utile

Y a-t-il quelque chose de mal à exporter / importer le magasin comme celui-ci?

Cela ne fonctionnera pas si vous affichez votre application sur le serveur, car vous souhaitez avoir store instance

Pourquoi ne pas faire cela à la place?

import { Component } from 'react';
import { connect } from 'react-redux';
import * as actions from './actions';

let createHandlers = function(dispatch) {
  let onClick = function(node, data) {
    dispatch(actions.nodeClicked(data))
  };

  return {
    onClick,
    // other handlers
  };
}

class Controls extends Component {
  constructor(props) {
    super(props);
    this.handlers = createHandlers(this.props.dispatch);
  }

  render() {
    // pass this.handlers anywhere you'd like
  }
}

export default connect()(Controls);

Tous les 10 commentaires

Consultez https://github.com/rackt/react-redux pour une méthode d'aide pour lier la distribution à vos composants

Plus précisément, à partir de https://redux.js.org/docs/basics/UsageWithReact.html

Tout composant encapsulé avec un appel connect () recevra une fonction de répartition en tant que prop, et tout état dont il a besoin de l'état global.

  • Commentaire mis à jour avec un nouveau lien vers la page pertinente, où le contenu n'existe plus

Y a-t-il quelque chose de mal à exporter / importer le magasin comme celui-ci?

Cela ne fonctionnera pas si vous affichez votre application sur le serveur, car vous souhaitez avoir store instance

Pourquoi ne pas faire cela à la place?

import { Component } from 'react';
import { connect } from 'react-redux';
import * as actions from './actions';

let createHandlers = function(dispatch) {
  let onClick = function(node, data) {
    dispatch(actions.nodeClicked(data))
  };

  return {
    onClick,
    // other handlers
  };
}

class Controls extends Component {
  constructor(props) {
    super(props);
    this.handlers = createHandlers(this.props.dispatch);
  }

  render() {
    // pass this.handlers anywhere you'd like
  }
}

export default connect()(Controls);

@gaearon a l'air super, merci!

@gaearon En fait, après l'avoir essayé, je reçois undefined pour this.props.dispatch .

Les parties pertinentes de mon code:

import React from 'react';
import {Component} from 'react';
import {connect} from 'react-redux';
import * as vizActions from './vizActions';
import viz from './lib/viz';

let createHandlers = function(dispatch) {
  return {
    click: function(DOMNode, data) {
        // Getting undefined here
        dispatch(vizActions.setSelectedNode(data));
    }
  };
}

class Viz extends Component {
  constructor(props) {
    super(props);
    console.log(this.props.dispatch); // <- Getting undefined here
    // Passing the redux dispatch to be used in handlers function
    this.handlers = createHandlers(this.props.dispatch);
  }

  componentDidMount() {
    // Create Viz
  }

  componentDidUpdate() {
    // Update Viz Data, passing in this.handlers
  }

  render() {
    return <div id="viz"></div>;
  }
};


function mapStateToProps(state) {
  return {
    // Pass the network used for the viz as a prop
    network: state.get('visualization').get('network')
  };
}

export const VizContainer = connect(mapStateToProps, vizActions)(Viz);

Cependant, après avoir lu un autre numéro (https://github.com/rackt/redux/issues/239), j'ai réalisé que je liais réellement mes actions à this.props via connect() , donc je peux passez simplement l'action nécessaire lorsque j'appelle createHandlers() . Ce n'est peut-être pas la meilleure approche, mais cela fonctionne maintenant:

...
let createHandlers = function(action) {
  return {
    click: function(DOMNode, data) {
                // This works now
        action(data);
    }
  };
}

class Viz extends Component {
  constructor(props) {
    super(props);
    // Passing the redux dispatch to be used in handlers function
    this.handlers = createHandlers(this.props.setSelectedNode); // passing action creator function
  }
...

En fait, après l'avoir essayé, je ne suis plus défini pour this.props.dispatch.

Parce que vous n'exécutez pas le code que j'ai publié. Dans le code, j'ai posté connect je n'ai pas reçu de deuxième paramètre. Vous y passez vizActions . C'est pourquoi vous n'obtenez pas dispatch . Si vous supprimez vizActions de connect call, vous l'obtiendrez.

Les deux approches sont cependant équivalentes, alors choisissez ce qui vous convient le mieux.

: +1: Ok, ça a du sens maintenant. Merci pour l'aide!

Un peu tard à la fête, mais répondre juste au cas où cela aiderait quelqu'un plus tard (y compris moi-même).
Si un mapDispatchToProps est nécessaire (le deuxième paramètre passé pour se connecter), ajoutez explicitement dispatch comme l'une des clés.

const mapDispatchToProps = (dispatch) => {
  return {
    dispatch,

    // ... other custom mapped dispatch functions ...
    myFunction: (myParam) => {
      dispatch(State.Actions...)
    },
  }
}

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

Salut. J'ai aussi ce problème.
@gaearon , je suis reconnaissant de vos conseils. J'ai utilisé vos solutions, mais je ne peux pas les comprendre et les utiliser.
Je ne sais pas comment utiliser this.handlers Lorsque l'utilisateur clique sur une carte, j'envoie cet identifiant de carte aux composants du parent et lance l'action.

import React , { Component } from 'react';
import { Col } from "react-bootstrap";
import { connect } from 'react-redux';
import Home from "../components/Home";
import { fetchHome, asideArticle } from "../actions/index";

let createHandlers = function(dispatch) {
    let onClick = function(node, articleId) {
        dispatch(asideArticle(articleId))
    };
    return {
        onClick
    };
}

class HomeContainer extends Component {
    constructor(props) {
        super(props);
        this.handlers = createHandlers(this.props.dispatch); 
        console.log('constructor => this.props.dispatch => Result => dispatch is undefined);
    }
    componentDidMount() {
        this.props.fetchHome();
    }

    render() {
        const { homeData, article } = this.props;


       // 
        return (
            <Col>
                <Home homeData={homeData} asideArticle={(articleId) => asideArticle(articleId) } />
            </Col>
        );
    }
}

const mapStateToProps = state => ({
    homeData : state.home,
    article: state
});

function loadData(store){
    return store.dispatch(fetchHome());
}

export default {
    loadData,
    component: connect(mapStateToProps, { fetchHome, asideArticle })(HomeContainer)
}

Comment puis-je utiliser this.handlers et passer le articleId après avoir passé l'événement click pour le transmettre?
Et que signifie le paramètre node dans le function(node, articleId) et que fait-il?

@EhsanFahami :

Ceci est un bug tracker, pas un système de support. Pour les questions d'utilisation, veuillez utiliser Stack Overflow ou Reactiflux où il y a beaucoup plus de personnes prêtes à vous aider - vous obtiendrez probablement une meilleure réponse plus rapidement. Merci!

Cette page vous a été utile?
0 / 5 - 0 notes

Questions connexes

cloudfroster picture cloudfroster  ·  3Commentaires

timdorr picture timdorr  ·  3Commentaires

benoneal picture benoneal  ·  3Commentaires

captbaritone picture captbaritone  ·  3Commentaires

parallelthought picture parallelthought  ·  3Commentaires