Redux: 从React组件文件中调用store.dispatch()吗?

创建于 2015-10-19  ·  10评论  ·  资料来源: reduxjs/redux

很抱歉,这是已经解决的问题,但是在问题中进行关键字搜索并没有带来任何帮助。

如果要从组件文件中调用store.dispatch(someAction) ,访问store实例的正确方法是什么?

现在,我有以下可行的方法,但是我不确定这是正确的方法:

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
  }
});

这样导出/导入商店有什么问题吗? 我想我可以将单击处理程序作为React组件的一部分创建并调用this.context.store ,但是实际上有大约十二种不同的事件处理程序传递给了D3可视化,因此在此操作中并不实际情况。

question

最有用的评论

这样导出/导入商店有什么问题吗?

如果您在服务器上渲染应用程序,这将无法正常工作,因为您希望每个请求在服务器上具有不同的store实例。 这就是为什么我们从不建议在文档中使用这种方法的原因。

为什么不这样做呢?

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);

所有10条评论

查看https://github.com/rackt/react-redux以获取帮助程序方法,以将分派绑定到组件

具体来说,来自https://redux.js.org/docs/basics/UsageWithReact.html

任何用connect()调用包装的组件都将收到一个派发函数作为prop,以及它从全局状态中需要的任何状态。

  • 更新了评论,并带有指向相关页面的新链接,其中内容不再存在

这样导出/导入商店有什么问题吗?

如果您在服务器上渲染应用程序,这将无法正常工作,因为您希望每个请求在服务器上具有不同的store实例。 这就是为什么我们从不建议在文档中使用这种方法的原因。

为什么不这样做呢?

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看起来不错,谢谢!

@gaearon实际上,在尝试之后,我得到了this.props.dispatch undefined this.props.dispatch

我的代码的相关部分:

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);

但是,在阅读了另一个问题(https://github.com/rackt/redux/issues/239)之后,我意识到我实际上是通过connect()操作绑定到this.props connect() ,所以我可以只需在调用createHandlers()时通过必要的操作即可。 也许这不是最好的方法,但现在可以使用:

...
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
  }
...

实际上,在尝试之后,我对this.props.dispatch的定义变得不确定。

因为您没有运行我发布的代码。 在我发布的代码中, connect没有收到第二个参数。 您在那里传递vizActions 。 这就是为什么您没有获得dispatch 。 如果从connect通话中删除vizActions ,您将得到它。

尽管这两种方法是等效的,但是请选择最适合您的方法。

:+1:好的,这很有意义。 谢谢您的帮助!

Kinda迟到了聚会,但回复以防万一对以后的某个人(包括我自己)有所帮助。
如果需要自定义mapDispatchToProps (传递给连接的第二个参数),则显式添加dispatch作为键之一。

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

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

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

你好我也有这个问题。
@gaearon ,我感谢您的指导。 我已经使用了您的解决方案,但是我无法理解和使用它们。
我不知道如何使用this.handlers当用户单击卡片时,我将该卡片ID发送给父母的组件并执行操作。

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)
}

我如何使用this.handlers并在通过click事件传递后传递articleId
node参数在function(node, articleId)意味着什么,它有什么作用?

@EhsanFahami

这是一个错误跟踪器,而不是支持系统。 对于使用方面的问题,请使用Stack Overflow或Reactiflux,那里有很多人愿意帮助您-您可能会更快地得到更好的答案。 谢谢!

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

vslinko picture vslinko  ·  3评论

ilearnio picture ilearnio  ·  3评论

benoneal picture benoneal  ·  3评论

captbaritone picture captbaritone  ·  3评论

jimbolla picture jimbolla  ·  3评论