dispatch(react-redux)
Why use redux at all, when you can pass state through props in react just fine and it works? This was my thought when we first saw the redux information, and I’m sure I wasn’t alone. In theory, yea, you can just pass state around components through props, sure. This works if the application is simple and doesn’t have many components, once the application becomes larger in size and you need to start accessing state from child components in other components that is where using redux is a life saver. In React alone if you wanted for example childComponentA
to have access to the state within childComponentB
you would first have to find a parent component that both of these children components share. In small simple apps these components may have the same parent component and it is simple. You would just have to pass the state of the child to the parent and then back down to the other child. Now once the app gets more complicated and larger, it could be possible that the parent they share could be 6–8 other components up the tree. You would have to take the state form childComponentB
and pass it up parent components up to the 6th layer where the shared parent is and then pass that state back down another 6 layers to childComponentA
. This could get complicated and confusing quickly. This is where Redux and the redux store come into play and despite all the confusion at first is a major help.
The Redux Store
The Redux store is simply just the state of your entire app. It will always have the most up to date, most recent state of your app. It will always be the single source of truth because the application will have one single ‘state tree’ within the store. State within the store is essentially read only, it can only be changed with pure functions (reducers). There are certain ‘rules’ per say as to how to change the state inside of the store as well as how to access the information within the store. The major plus of redux is that the state that you have in the store can be accessed by all components in the application. The getState()
function gives our components access to the state within the store, getState()
is the only way to access the information in the store. If this is the only way to access the information, you guessed it, there is only one way to change the information as well. To change the state within the store we use another function dispatch(action)
to achieve this for us. The dispatch()
function takes in an argument of an action
, (more on actions later) , and this is the only way to make a state change to the store. There are other functions that we could use as well with the store. Redux is nothing more than a state management tool, the store is where it keeps the most update to date version of state for our application, in an easy to access place, but we need to make sure that we connect our react app to the redux store correctly for it to work.
Connecting React to Redux
First things first, React doesn’t come with Redux, so you have to add it with a simple npm install react-redux
. Once installed we will then wrap our entire application within the <Provider>
, I did this within my index.js
file :
import React from 'react'
import ReactDOM from 'react-dom'
import { Provider } from 'react-redux'
import store from './store'ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
)
Doing this now gives our entire application access to the state within the redux store without having to explicitly pass it into every component that we need it. Wrapping the entire application not only grants that access to the components but the only way we can use connect()
is if it is inside of the <Provider>
. The connect()
function is, well, what connects the react app to the redux store. What this function does is that it provides the connected component access to the information inside the store, as well as the functions that it can use to dispatch actions to the store. The connect()
function can have at most four arguments, but all four arguments are optional, it all depends on what you need. mapStateToProps
and mapDispatchToProps
are the most common ones that can be used. What mapStateToProps
does is pretty self-explanatory in its name, but it connects the Redux store state to the props of the connected component, giving that component the information needed from the store without having to pass it from great, great, great grandparent with just basic React. mapDispatchToProps
connects Redux actions to the connected components props so that this connected component will be able to send information back to the Redux store. These actions go to the reducer which will determine how the application state within the store will change.
The reducer changes the state within the redux store according to what actions it receives. Our entire application should essentially only have one reducer that is passed into the createStore
function as an argument. As applications grow larger and more complex they will have more than one reducer built into them and this is where combineReducers()
function comes into play. combineReducers()
is a helper function that can take different reducing functions and can turn those different reducers into a single reducer that is then passed into createStore
. An example of combineReducers
:
import {createStore, combineReducers } from 'redux'
import playerReducer from './Player/PlayerReducer'
import CourseReducer from './Course/CourseReducer'const rootReducer = combineReducers({
player: playerReducer,
course: CourseReducer,
})const store = createStore(
rootReducer,
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
)export default store
Simple enough, but as every thing in Redux there are some rules, your reducer must always return state
even if undefined
is passed to the reducer. Giving your reducers an initial state
as default will always have the reducer return the latest version of state if the action passed to the reducer is not one that it is familiar with. The combineReducers()
function will always check to make sure that these rules are being followed, it will pass an undefined
value to the reducers to test the reducer and make sure that it still returns state. When building your reducers you have to make sure that they are built correctly with a default state value even if you don’t intend your application to ever pass undefined
.
Hopefully this has helped you in answering the famous question that I’m sure has to be asked by everyone when they first look at Redux, why use Redux instead of just React alone? Redux is a very confusing and tricky sea to maneuver, but once you realize how all the moving parts within it work, Redux becomes a very powerful tool that can help you build some incredible applications.