We have a series of articles about react and how it works with redux:
-Redux without React
-Integrating React with Redux
By now, you should have known how Redux works on its own, what are actions, action creators and reducers, and how to start integrating Redux with React.
Let’s continue our talk about how React-Redux handles actions, action creators, reducers, redux-store, how to fetch data from state and how to call our action creators.
Combine Reducers and create Store:
We learned previously that after we combine our reducers we create what’s so called Redux-Store that contains all of our reducers and the global state of our application.
Provider and Connect:
We are going to take that store and pass it as a prop to the Provider which will be rendered at the top of our component tree, wrapping our App component.
The Provider can be considered as a reference to the Store and it’s the only component that can access the state and alter it directly. Other components also can’t deal with Provider directly. Components can only deal with the Connect component which in turn communicates with the Provider with a system of communication inside of React called the context system.
Whenever a component needs to access the data stored in the store then we are going to use Connect. We wrap that component by Connect and then it’s called connected component which means it’s now connected to the state store.
Simply at any point of time a component needs to render some data from the state we tell the Connect which in turn reaches back to the Provider to get the needed data from the redux-store and sends it back to the Connect that passes this data as props to the component.
But to alter the state we need action creators which are not stored in the redux-store.
When we used Redux alone we used to call action creators to return an action that we send to the store through dispatch function. Now using React-Redux we are going to deal with action creators in a different way. We tell Connect that we need to call a specific action creator from within our component. Then Connect passes this action creator to our component also as a prop. And after the call, Connect passes the action to the dispatch function in the redux-store.
In the previous part we installed React-Redux and configured Provider in the index.js and Connect in desired components. But you might think about how to structure your folders and where to put all of the actions and reducers.
Well, it’s totally up to you but the best way is to get all of the actions in a separate folder same as the reducers. Each in its own folder inside your src folder.
Now enough talking and let’s see some code to get a clearer picture.
Starting with reducers:
Here’s an example of a reducer that adds a new record to the state.
P.S. You can separate each action type in its own reducer or join them together using switch case like the example.
You can write as many reducers as you want and at the end call combineReducers in the same file or in a different one but of course in that case, don’t forget to export the reducers.
Now we have seen reducers and in the previous part we learned how to create store out of the combined reducers and how to configure Provider component, let’s move on to action creators.
Setting action creators:
Here’s an example of a simple action creator that returns action with type and payload properties. It can’t be more simple.
Before, I’ve mentioned that components don’t communicate with Provider directly, instead they use Connect to do all the communication for them. And we have learned how to wire up the Connect to our components.
Now let’s see how components actually uses Connect to access the state.
First: Fetching data from state:
Components can fetch data from state using mapStateToProps function. Before explaining what is that function and what does it do let’s see the next code.
First of all, mapStateToProps function can be called by any other name, but by convention we call it like that. And from this name we can guess what it does. It does map our state to props which means we use it to extract some data from state and turn it into props so that the component can deal with it. And when we pass it to Connect we actually tell Connect to go fetch the state from the store and then pass it to mapStateToProps function which returns an object containing our new prop holding values from the global state. And then as shown above we can access this data just like any other props by using props.records syntax.
Whenever the state is updated, mapStateToProps is called causing component to rerender.
P.S. If you want to use connect but you don’t need mapStateToProps, you can simply write null instead of mapStateToProps but you can’t leave it empty.
Second: Calling action creators:
Just like we used mapStateToProps to access state, for actions there is mapDispatchToProps function. Let’s have a look on it.
As you can see, it’s the same component. But here we use mapDispatchToProps function which is just like mapStateToProps but instead of accessing the state, mapDispatchToProps access the dispatch method of the redux store. It also returns an Obj with key of prop name and the value of dispatching the action creator.
We pass it to Connect but it must be passed after mapStateToProps. And after that we can use it in events -as made in the above code- or in whatever action in which we want to call on the action creator. We access it also through props obj.
There is another way to use mapDispatchToProps without actually writing it in the code which is:
As you can see, we didn’t use mapDispatchToProps, instead we passed the final obj to Connect directly and this way we can use props.addNewRecord just like the other syntax.
You may ask why causing our selves all of this headache of passing the action creators to Connect then call it through props instead of just calling it directly in the component.
The answer is that Redux is no magic !! It can’t detect by itself anytime we call action creator or that a function in my component returns an action obj and that it must use it to update our state. So for Redux action creators at the end are just functions that return objects and nothing more and they won’t have any impact on the state. So if we wanted an action to really update the state we have to dispatch it. And that is what happens with Connect and mapDispatchToProps.
So to sum up the React-Redux cycle
-We create our reducers and action creators.
-We combine our reducers and create the redux store.
-We wrap our application with Provider and pass it the created store.
-We use Connect in any component and use with it:
mapStateToProps, if we wanted to fetch data from state.
mapDispatchToProps, if we wanted to call on some action creators.