рдореИрдВ рдорд╛рдлреА рдорд╛рдБрдЧрддрд╛ рд╣реВрдБ рдЕрдЧрд░ рдпрд╣ рдХреБрдЫ рдРрд╕рд╛ рд╣реИ рдЬреЛ рдкрд╣рд▓реЗ рд╣реА рд╕рд╛рдл рд╣реЛ рдЪреБрдХрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдореБрджреНрджреЛрдВ рдореЗрдВ рдПрдХ рдЦреЛрдЬрд╢рдмреНрдж рдЦреЛрдЬ рдиреЗ рдХреБрдЫ рднреА рдРрд╕рд╛ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬреЛ рдорджрдж рдХрд░рддрд╛ рд╣реЛред
рдЕрдЧрд░ рдореИрдВ рдХрд┐рд╕реА рдШрдЯрдХ рдлрд╝рд╛рдЗрд▓ рд╕реЗ 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
}
});
рдХреНрдпрд╛ рд╕реНрдЯреЛрд░ рдХреЛ рдЗрд╕ рддрд░рд╣ рд╕реЗ рдирд┐рд░реНрдпрд╛рдд / рдЖрдпрд╛рдд рдХрд░рдиреЗ рдореЗрдВ рдХреБрдЫ рдЧрд▓рдд рд╣реИ? рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдореИрдВ рд░рд┐рдПрдХреНрдЯрд░ рдШрдЯрдХ рдХреЗ рд╣рд┐рд╕реНрд╕реЗ рдХреЗ рд░реВрдк рдореЗрдВ рдмрд╕ рдХреНрд▓рд┐рдХ рд╣реИрдВрдбрд▓рд░ рдмрдирд╛ рд╕рдХрддрд╛ рд╣реВрдВ рдФрд░ this.context.store
рдХреЙрд▓ рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВ, рд▓реЗрдХрд┐рди рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд▓рдЧрднрдЧ рдПрдХ рджрд░реНрдЬрди рдЕрд▓рдЧ-рдЕрд▓рдЧ рдЗрд╡реЗрдВрдЯ рд╣реИрдВрдбрд▓рд░ рд╣реИрдВ рдЬреЛ рдбреА 3 рд╡рд┐рдЬрд╝реБрдЕрд▓рд╛рдЗрдЬрд╝реЗрд╢рди рдореЗрдВ рдкрд╛рд╕ рд╣реЛ рдЬрд╛рддреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рдирд╣реАрдВ рд╣реИ рдкрд░рд┐рд╕реНрдерд┐рддрд┐ред
рдЕрдкрдиреЗ рдШрдЯрдХреЛрдВ рдХреЛ рдкреНрд░реЗрд╖рдг рдХреЗ рд▓рд┐рдП рд╕рд╣рд╛рдпрдХ рд╡рд┐рдзрд┐ рдХреЗ рд▓рд┐рдП https://github.com/rackt/react-redux рджреЗрдЦреЗрдВ
рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ, https://redux.js.org/docs/basics/UsageWithReact.html рд╕реЗ
рдХрдиреЗрдХреНрдЯ () рдХреЙрд▓ рдХреЗ рд╕рд╛рде рд▓рд┐рдкрдЯреЗ рдХрд┐рд╕реА рднреА рдШрдЯрдХ рдХреЛ рдкреНрд░реЙрдк рдХреЗ рд░реВрдк рдореЗрдВ рдПрдХ рдкреНрд░реЗрд╖рдг рд╕рдорд╛рд░реЛрд╣ рдкреНрд░рд╛рдкреНрдд рд╣реЛрдЧрд╛, рдФрд░ рдХрд┐рд╕реА рднреА рд░рд╛рдЬреНрдп рдХреЛ рд╡реИрд╢реНрд╡рд┐рдХ рд░рд╛рдЬреНрдп рд╕реЗ рдЗрд╕рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреАред
рдХреНрдпрд╛ рд╕реНрдЯреЛрд░ рдХреЛ рдЗрд╕ рддрд░рд╣ рд╕реЗ рдирд┐рд░реНрдпрд╛рдд / рдЖрдпрд╛рдд рдХрд░рдиреЗ рдореЗрдВ рдХреБрдЫ рдЧрд▓рдд рд╣реИ?
рдпрджрд┐ рдЖрдк рд╕рд░реНрд╡рд░ рдкрд░ рдЕрдкрдиреЗ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ рдкреНрд░рд╕реНрддреБрдд рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рддреЛ рдпрд╣ рдХрд╛рдо рдирд╣реАрдВ рдХрд░реЗрдЧрд╛ рдХреНрдпреЛрдВрдХрд┐ рдЖрдк рд╕рд░реНрд╡рд░ рдкрд░ рдЕрдиреБрд░реЛрдз рдХреЗ рдЕрдиреБрд╕рд╛рд░ 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 рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдЗрд╕реЗ рдЖрдЬрд╝рдорд╛рдиреЗ рдХреЗ рдмрд╛рдж, рдореБрдЭреЗ 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) рдкрдврд╝рдиреЗ рдХреЗ рдмрд╛рдж рдореБрдЭреЗ рдорд╣рд╕реВрд╕ рд╣реБрдЖ рдХрд┐ рдореИрдВ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ 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
}
...
рджрд░рдЕрд╕рд▓, рдЗрд╕реЗ рдЖрдЬрдорд╛рдиреЗ рдХреЗ рдмрд╛рдж, рдореИрдВ рдЗрд╕рдХреЗ рд▓рд┐рдП рдЕрдкрд░рд┐рднрд╛рд╖рд┐рдд рд╣реЛ рд░рд╣рд╛ рд╣реВрдВред
рдХреНрдпреЛрдВрдХрд┐ рдЖрдк рдореЗрд░реЗ рджреНрд╡рд╛рд░рд╛ рдкреЛрд╕реНрдЯ рдХрд┐рдП рдЧрдП рдХреЛрдб рдХреЛ рдирд╣реАрдВ рдЪрд▓рд╛ рд░рд╣реЗ рд╣реИрдВред рдХреЛрдб рдореЗрдВ рдореИрдВрдиреЗ connect
рдкреЛрд╕реНрдЯ рдХрд┐рдпрд╛ vizActions
рд╣реИрдВред рдпрд╣реА рдХрд╛рд░рдг рд╣реИ рдХрд┐ рдЖрдкрдХреЛ dispatch
рдирд╣реАрдВ рдорд┐рд▓рддреЗ рд╣реИрдВред рдпрджрд┐ рдЖрдк vizActions
рдХреЛ connect
рдХреЙрд▓ рд╕реЗ рдирд┐рдХрд╛рд▓рддреЗ рд╣реИрдВ, рддреЛ рдЖрдкрдХреЛ рдпрд╣ рдорд┐рд▓ рдЬрд╛рдПрдЧрд╛ред
рд╣рд╛рд▓рд╛рдВрдХрд┐ рджреЛрдиреЛрдВ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╕рдорд╛рди рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рдЖрдкрдХреЗ рд╕рд╛рде рдЬреЛ рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рд╣реИ рдЙрд╕реЗ рдкрдврд╝реЗрдВред
: +1: рдареАрдХ рд╣реИ, рдЕрдм рд╕рдордЭ рдореЗрдВ рдЖрддрд╛ рд╣реИред рд╕рд╣рд╛рдпрддрд╛ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж!
рдХрд┐рдиреНрджрд╛ рдХреЛ рдкрд╛рд░реНрдЯреА рдХреЗ рд▓рд┐рдП рджреЗрд░ рд╣реЛ рдЧрдИ, рд▓реЗрдХрд┐рди рд╕рд┐рд░реНрдл рдорд╛рдорд▓реЗ рдореЗрдВ рдЬрд╡рд╛рдм рджреЗрдиреЗ рд╕реЗ рдЙрд╕реЗ рдмрд╛рдж рдореЗрдВ (рдЦреБрдж рд╕рд╣рд┐рдд) рдХрд┐рд╕реА рдХреА рдорджрдж рдорд┐рд▓рддреА рд╣реИред
рдпрджрд┐ рдПрдХ рдХрд╕реНрдЯрдо mapDispatchToProps
рдХреА рдЬрд░реВрд░рдд рд╣реИ (рдХрдиреЗрдХреНрдЯ рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП рджреВрд╕рд░рд╛ рдкреИрд░рд╛рдо), рддреЛ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдХреБрдВрдЬреА рдореЗрдВ рд╕реЗ рдПрдХ рдХреЗ рд░реВрдк рдореЗрдВ dispatch
рдЬреЛрдбрд╝реЗрдВред
const mapDispatchToProps = (dispatch) => {
return {
dispatch,
// ... other custom mapped dispatch functions ...
myFunction: (myParam) => {
dispatch(State.Actions...)
},
}
}
export default connect( mapStateToProps, mapDispatchToProps )(Viz);
рдирдорд╕реНрддреЗред рдореБрдЭреЗ рднреА рдпрд╣ рд╕рдорд╕реНрдпрд╛ рд╣реИред
@ рдЧреЗрдпреЗрд░реЙрди , рдореИрдВ рдЖрдкрдХреЗ рдорд╛рд░реНрдЧрджрд░реНрд╢рди рдХреЗ рд▓рд┐рдП рдЖрднрд╛рд░реА рд╣реВрдВред рдореИрдВрдиреЗ рдЖрдкрдХреЗ рд╕рдорд╛рдзрд╛рдиреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдореИрдВ рдЙрдиреНрд╣реЗрдВ рд╕рдордЭ рдирд╣реАрдВ рд╕рдХрддрд╛ рдФрд░ рдЙрдирдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛ред
рдореБрдЭреЗ рдирд╣реАрдВ рдкрддрд╛ рдХрд┐ this.handlers
рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреИрд╕реЗ рдХрд░реЗрдВ рдЬрдм рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХрд┐рд╕реА рдХрд╛рд░реНрдб рдкрд░ рдХреНрд▓рд┐рдХ рдХрд░рддрд╛ рд╣реИ, рддреЛ рдореИрдВ рдЙрд╕ рдХрд╛рд░реНрдб рдЖрдИрдбреА рдХреЛ рдорд╛рддрд╛-рдкрд┐рддрд╛ рдХреЗ рдШрдЯрдХреЛрдВ рдХреЛ рднреЗрдЬрддрд╛ рд╣реВрдВ рдФрд░ рдХрд╛рд░реНрд░рд╡рд╛рдИ рдЪрд▓рд╛рддрд╛ рд╣реВрдВред
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)
рдФрд░ рдХреНрдпрд╛ рдХрд░рддрд╛ рд╣реИ рдпрд╣ рдХрд░рддреЗ рд╣реИрдВ?
@ рдПрд╣рд╕рд╛рдирдлрд╛рдореА :
рдпрд╣ рдПрдХ рдмрдЧ рдЯреНрд░реИрдХрд░ рд╣реИ, рд╕рдорд░реНрдерди рдкреНрд░рдгрд╛рд▓реА рдирд╣реАрдВ рд╣реИред рдЙрдкрдпреЛрдЧ рдХреЗ рдкреНрд░рд╢реНрдиреЛрдВ рдХреЗ рд▓рд┐рдП, рдХреГрдкрдпрд╛ рд╕реНрдЯреИрдХ рдУрд╡рд░рдлреНрд▓реЛ рдпрд╛ рд░рд┐рдПрдХреНрдЯрд┐рдлреНрд▓рдХреНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ рдЬрд╣рд╛рдВ рдЖрдкрдХреА рд╕рд╣рд╛рдпрддрд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рдЕрдзрд┐рдХ рд▓реЛрдЧ рддреИрдпрд╛рд░ рд╣реИрдВ - рдЖрдкрдХреЛ рд╢рд╛рдпрдж рдмреЗрд╣рддрд░ рдЙрддреНрддрд░ рдорд┐рд▓реЗрдЧрд╛ред рдзрдиреНрдпрд╡рд╛рдж!
рд╕рдмрд╕реЗ рдЙрдкрдпреЛрдЧреА рдЯрд┐рдкреНрдкрдгреА
рдпрджрд┐ рдЖрдк рд╕рд░реНрд╡рд░ рдкрд░ рдЕрдкрдиреЗ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ рдкреНрд░рд╕реНрддреБрдд рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рддреЛ рдпрд╣ рдХрд╛рдо рдирд╣реАрдВ рдХрд░реЗрдЧрд╛ рдХреНрдпреЛрдВрдХрд┐ рдЖрдк рд╕рд░реНрд╡рд░ рдкрд░ рдЕрдиреБрд░реЛрдз рдХреЗ рдЕрдиреБрд╕рд╛рд░
store
ред рдЗрд╕рд▓рд┐рдП рд╣рдо рдбреЙрдХреНрд╕ рдореЗрдВ рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреА рдЕрдиреБрд╢рдВрд╕рд╛ рдХрднреА рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВредрдЗрд╕рдХреЗ рдмрдЬрд╛рдп рдРрд╕рд╛ рдХреНрдпреЛрдВ рдирд╣реАрдВ рдХрд░рддреЗ?