これがすでに解決されているものである場合はお詫び申し上げますが、問題のキーワード検索では何の役にも立ちませんでした。
コンポーネントファイルから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ビジュアライゼーションに渡されるイベントハンドラーは約12種類あるため、これは実際には実用的ではありません。状況。
コンポーネントにディスパッチをバインドするためのヘルパーメソッドについては、 https://github.com/rackt/react-reduxを確認して
具体的には、 https://redux.js.org/docs/basics/UsageWithReact.htmlから
connect()呼び出しでラップされたコンポーネントは、小道具としてディスパッチ関数を受け取り、グローバル状態から必要な状態を受け取ります。
このようなストアのエクスポート/インポートに問題はありますか?
サーバー上のリクエストごとに異なる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
を取得しています。
私のコードの関連部分:
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)を読んだ後、私は私が実際に私の行動を結合していますことに気づい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
は2番目のパラメーターを受け取りませんvizActions
渡します。 そのため、 dispatch
取得できません。 connect
通話からvizActions
を削除すると、それを取得できます。
どちらのアプローチも同等ですが、自分に最適な方法を選択してください。
:+1:わかりました、それは今では理にかなっています。 助けてくれてありがとう!
ちょっとパーティーに遅れましたが、後で誰か(私を含む)を助ける場合に備えて返信します。
カスタムmapDispatchToProps
が必要な場合(接続に渡される2番目のパラメーター)、キーの1つとして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
を渡し、 articleId
を渡すにはどうすればよいですか?
そして、 node
パラメータはfunction(node, articleId)
で何を意味し、それは何をしますか?
@EhsanFahami :
これはバグトラッカーであり、サポートシステムではありません。 使用法に関する質問については、Stack OverflowまたはReactifluxを使用してください。多くの人があなたを助けてくれる準備ができています。おそらく、より良い答えがより早く得られるでしょう。 ありがとう!
最も参考になるコメント
サーバー上のリクエストごとに異なる
store
インスタンスが必要なため、サーバー上でアプリをレンダリングする場合、これは機能しません。 そのため、ドキュメントではこのアプローチを推奨していません。代わりにこれをしないのはなぜですか?