Perhaps I am not wrapping my head around redux, but all the examples I've seen don't really access state too much between containers and so I haven't seen much usage of store.getState(), but even if you want to dispatch, you need access to store, right?
So, other than importing import store from 'path/to/store/store'
in every file that I want to getState() or "dispatch", how do I get access to that state because if I don't include it, store is undefined.
If you use the
react-redux
package, you'll end up wrapping your components in aProvider
with astore
prop. This sets up your single store in a React context, which is then accessed from theconnect
method in child components. Theconnect
method takes two functions (mapStateToProps and mapDispatchToProps), which are your hooks for getting state from the store and dispatching messages.Take a look here for more information
In general you want to only make top-level container components ones that have access to the store - they will pass down any necessary data or action dispatches as props to their children components. This is the difference between a "smart" and a "dumb" component - "smart" components know about the Redux store/state, while "dumb" components just get props passed to them and have no idea about the bigger application state.
However, even just passing the store to container components can become tedious. That's why React-Redux provides one component out of the box that wraps your entire application. Check it out in the docs. This is the
Provider
component and when you wrap your whole app with it, you only pass the store to a component once:As you can see here, I have a separate configuration file just for my store as there is a lot of modification you can do and for any remotely complex app, you'll find yourself doing the same for things like using compose to apply middleware.
Then any of your remaining "smart" components (generally wrappers) need to listen to the store. This is accomplished using the connect method. This allows you to map pieces of the state to your component properties as well as dispatch actions as properties.
Because you are always passing down dispatch actions and data to your children component as properties, you just reference those on that component with
this.props
.Building off the example above, you'll see that because I passed
this.props.something
toChildComponent1
, it has access to thesomething
data from the store but it does not have access to thegetSomething
dispatch action. Likewise,ChildComponent2
only has access to thegetSomething
dispatch action but not thesomething
data. This means that you only expose components to exactly what they need from the store.For example, because
ChildComponent2
was passed down the dispatch action asgetSomething
, in myonClick
I can callthis.props.getSomething
and it will call the dispatch action without needing any access to the store. In the same way it can continue to pass downgetSomething
to another child component and that component could call it and/or pass it down and the cycle could continue indefinitely.Edit from the comments
While this doesn't pertain directly to the question, in the comments you seemed a little confused about actions. I did not actually define the action
getSomething
here. Instead it is usual in Redux apps to put all of your action definitions in a separate file calledactionCreators.js
. This contains functions that are named the same as your actions and return an object with atype
property and any other methods/data that action requires. For instance, here's a very simple exampleactionCreators.js
file:This action type is what your reducer would listen for to know which action was being fired.