很抱歉,这是已经解决的问题,但是在问题中进行关键字搜索并没有带来任何帮助。
如果要从组件文件中调用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可视化,因此在此操作中并不实际情况。
查看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,那里有很多人愿意帮助您-您可能会更快地得到更好的答案。 谢谢!
最有用的评论
如果您在服务器上渲染应用程序,这将无法正常工作,因为您希望每个请求在服务器上具有不同的
store
实例。 这就是为什么我们从不建议在文档中使用这种方法的原因。为什么不这样做呢?