How to get a simple submit from this.props using connect w / Redux?

I have a simple React component that I plug in (simple array / state mapping). In order not to refer to the context for the store, I would like to receive the “sending” directly from the props. I have seen others use this approach, but do not have access to it for some reason :)

Below are the versions of each npm dependency I'm currently using.

"react": "0.14.3", "react-redux": "^4.0.0", "react-router": "1.0.1", "redux": "^3.0.4", "redux-thunk": "^1.0.2" 

Here is the w / connect component

 class Users extends React.Component { render() { const { people } = this.props; return ( <div> <div>{this.props.children}</div> <button onClick={() => { this.props.dispatch({type: ActionTypes.ADD_USER, id: 4}); }}>Add User</button> </div> ); } }; function mapStateToProps(state) { return { people: state.people }; } export default connect(mapStateToProps, { fetchUsers })(Users); 

If you need to see the gearbox (nothing interesting, but here it is)

 const initialState = { people: [] }; export default function(state=initialState, action) { if (action.type === ActionTypes.ADD_USER) { let newPeople = state.people.concat([{id: action.id, name: 'wat'}]); return {people: newPeople}; } return state; }; 

If you need to see how my w / redux router is configured

 const createStoreWithMiddleware = applyMiddleware( thunk )(createStore); const store = createStoreWithMiddleware(reducers); var Route = ( <Provider store={store}> <Router history={createBrowserHistory()}> {Routes} </Router> </Provider> ); 

Update

It looks like if I omit my own mailing list in the connection (currently I show fetchUsers above), I would get a free send (just not sure if this will work with asynchronous actions). Do people mix and match, or is it all or nothing?

[mapDispatchToProps]

+69
javascript reactjs redux
Dec 24 '15 at 22:00
source share
3 answers

By default, mapDispatchToProps simply dispatch => ({ dispatch }) .
Therefore, if you do not specify the second argument to connect() , you will get dispatch as support in your component.

If you pass a custom function to mapDispatchToProps , you can do something with a function.
A few examples:

 // inject onClick function mapDispatchToProps(dispatch) { return { onClick: () => dispatch(increment()) }; } // inject onClick *and* dispatch function mapDispatchToProps(dispatch) { return { dispatch, onClick: () => dispatch(increment()) }; } 

To save some messages, Redux provides bindActionCreators() , which allows you to do this:

 // injects onPlusClick, onMinusClick function mapDispatchToProps(dispatch) { return { onPlusClick: () => dispatch(increment()), onMinusClick: () => dispatch(decrement()) }; } 

in it:

 import { bindActionCreators } from 'redux'; // injects onPlusClick, onMinusClick function mapDispatchToProps(dispatch) { return bindActionCreators({ onPlusClick: increment, onMinusClick: decrement }, dispatch); } 

or even shorter when the prop name names match the names of the creators of the action:

 // injects increment and decrement function mapDispatchToProps(dispatch) { return bindActionCreators({ increment, decrement }, dispatch); } 

If you want, you can add dispatch there manually:

 // injects increment, decrement, and dispatch itself function mapDispatchToProps(dispatch) { return { ...bindActionCreators({ increment, decrement }), // es7 spread syntax dispatch }; } 

There are no formal recommendations as to whether you should do this or not. connect() typically serves as the boundary between Redux-aware and Redux-unaware components. This is why we usually feel that we don’t need to introduce both the creators of the related actions and the dispatch . But if you think you need to do this, feel free to.

Finally, the template you are using right now is a shortcut that is even shorter than calling bindActionCreators . When all you do is return bindActionCreators , you can omit the call, rather than doing this:

 // injects increment and decrement function mapDispatchToProps(dispatch) { return bindActionCreators({ increment, decrement }, dispatch); } export default connect( mapStateToProps, mapDispatchToProps )(App); 

can be written as

 export default connect( mapStateToProps, { increment, decrement } // injects increment and decrement )(App); 

However, you will have to abandon this beautiful short syntax when you need something more ordinary, such as passing dispatch .

+197
Dec 24 '15 at 23:17
source share

You can usually mix and match depending on what you need.

You can pass dispatch as a prop if that is what you want:

 export default connect(mapStateToProps, (dispatch) => ({ ...bindActionCreators({fetchUsers}, dispatch), dispatch }))(Users); 

I'm not sure how fetchUsers used (as an async function?), But you usually use something like bindActionCreators to automatically bind the dispatch, and you don't have to worry about using dispatch directly in the connected components.

Using the dispatch directory, the type of the pair is a dumb, stand-alone component with a reduction. Which can make it less portable.

+4
Dec 24 '15 at 22:37
source share

While you can pass dispatch down as part of dispatchToProps , I would recommend that you avoid accessing the store or dispatch directly from your components. It seems you will be better served by passing the created related action to connect the 2nd argument to dispatchToProps

See the example that I posted here https://stackoverflow.com/a/166268/ about how to pass an “already connected action creator” in such a way that your components do not need to know directly about or are dependent on storage / dispatch.

Sorry for the short one. I will update additional information.

+1
Dec 24 '15 at 23:10
source share



All Articles