I'm studying react and I have an example like this
//index.js const store = createStore(reducer) render( <Provider store={store}> <AddTodo /> </Provider>, document.getElementById('root') ) //Apptodo.js import React from 'react' import { connect } from 'react-redux' import { addTodo } from '../actions' let AddTodo = ({ dispatch }) => { let input return ( <div> <form onSubmit={e => { e.preventDefault() if (!input.value.trim()) { return } dispatch(addTodo(input.value)) input.value = '' }}> .......
Why didn't it get this.pros.store
but simply call the dispatch() function ?
EDIT: How does it extract the dispatch
from this.pros
. Isn't the object this.pros.store
? and in this case why don't we just extract store
?
Thank you.
dispatch is a function of the Redux store. You call store. dispatch to dispatch an action. This is the only way to trigger a state change. With React Redux, your components never access the store directly - connect does it for you.
Now, react provides a better alternative to the connect() method and its arguments. The useDispatch and useSelector hooks are alternatives to mapDispatchToProps and mapStateToProps, respectively. The useDispatch hook is used to dispatch an action while useSelector hook is used to get the state from the redux store.
Redux doesn't have a Dispatcher or support many stores. Instead, there is just a single store with a single root reducing function. As your app grows, instead of adding stores, you split the root reducer into smaller reducers independently operating on the different parts of the state tree.
react-redux is the library that is passing these methods to your component as props.
dispatch() is the method used to dispatch actions and trigger state changes to the store. react-redux is simply trying to give you convenient access to it.
Note, however, that dispatch is not available on props if you do pass in actions to your connect function. In other words, in the code below, since I'm passing someAction
to connect, dispatch()
is no longer available on props.
The benefit to this approach, however, is that you now have the "connected" action available on your props that will automatically be dispatched for you when you invoke it.
import React, { PropTypes } from 'react'; import { connect } from 'react-redux'; import { someAction } from '../myActions'; const MyComponent = (props) => { // someAction is automatically dispatched for you // there is no need to call dispatch(props.someAction()); props.someAction(); }; export default connect(null, { someAction })(MyComponent);
Or if we were to use object destructuring as shown in the example you give...
const MyComponent = ({ someAction }) => { someAction(); };
It's important to note, however, that you must invoke the connected action available on props. If you tried to invoke someAction(), you'd be invoking the raw, imported action — not the connected action available on props. The example given below will NOT update the store.
const MyComponent = (props) => { // we never destructured someAction off of props // and we're not invoking props.someAction // that means we're invoking the raw action that was originally imported // this raw action is not connected, and won't be automatically dispatched someAction(); };
This is a common bug that people run into all the time while using react-redux. Following eslint's no-shadow rule can help you avoid this pitfall.
Your addTodo
component has access to the store's state and methods(e.g, dispatch, getState, etc). So, when you hooked up your React view with the Redux store via the connect
method, you had access to store's state and methods.
({ dispatch })
is simply using JS destructuring assignment to extract dispatch
from this.props
object.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With