This is an updated version of my past blog post, How to Implement Redux in A React Application, that now uses hooks, specifically useSelector
and useDispatch
. Feel free to poke around with this sample code.
Let’s get organized! There are many great tutorials that break down the concepts behind Redux or give a nice overview of how everything’s connected, but the fact is, Redux has a lot of starter code that is difficult to set up for the first time. If you understand the basics of Redux, here are some easy steps for initial setup in your React app.
Note: One of the most confusing things about Redux is that you can set up your files in many different ways. Here is one option that uses combineReducers.
Step 1: In your React app, run npm install redux && npm install react-redux
.
Step 2: In index.js
, import {Provider} from 'react-redux'
. Then, add <Provider>
tags around your <App>
component.
Step 3: Create a redux
folder in src
, and three files: actions.js
, reducer.js
and store.js
.
Step 4: In reducer.js
, import { combineReducers } from 'redux'
and set up your combineReducers.
Step 5: In store.js
, import { createStore } from 'redux'
and import rootReducer from './reducer'
. Use createStore
to… wait for it… create your store and include middleware in order to use Chrome Redux Developer Tools.
Step 6: In index.js
, import store from './redux/store'
and add the store to your <Provider>
component.
At this point, all of your files are set up. We will still need to add actions/reducers and our components, but the setup is complete. For the rest of this blog, I will walk you through useSelector
and useDispatch
using a sample application.
Our sample application has 3 components nested in a src > components
folder. Here’s the full code if you’d like to pull it down and test it yourself.
PostCard.jsx
PostsContainer.jsx
— PostCard
isn’t being used quite yet, but we’ll add it in soon.
NewPostForm.jsx
— Notice that the component has some local state because this is the only component that needs to keep track of what is being typed prior to submission.
As the last part of setup, be sure to import PostsContainer.jsx
in App.js
:
Step 7: In reducer.js
, create a postsReducer
to handle the posts portion of the state. Since there aren’t any actions yet, let’s start with the default of return state.
Step 8: In PostsContainer.jsx
, we need access to the posts stored in the store.
This is where Redux hooks really shine.
import {useSelector} from 'react-redux'
, and then useSelector
provides access to all of the state in store. We can select relevant portions of the store to make accessible in our component.
Ex: const posts = useSelector((state)=> state.posts)
At this point, if we already had posts stored in state, this would be enough to map over posts
and create PostCard
components. However, since we’re starting with no posts, we’ll need to add the useDispatch
hook.
Step 9: A few things have to happen at once to get an action going. First, add a case to your reducer. Think about what kind of information you’ll need in your payload in order to add a new post (text
& id
).
Step 10: In actions.js
, create a function that returns an action object when invoked. Don’t forget to export it!
Step 11: Back in NewPostForm.jsx
, import {useDispatch} from 'react-redux'
and import { addPost } from '../redux/actions'
. In your component, define dispatch: const dispatch = useDispatch()
. Now, you can call any of the actions you’ve imported by passing it into dispatch. Finally, update your handleOnSubmit
to use dispatch(addForm())
. Be sure that your object keys match the payload keys in your function in actions.js
.
Note: to generate a random id check out uuid.
And there you have it! Here’s the final product… a wonderfully boring, but functioning, post board.
Of course, this is only dealing with the frontend. To connect it to the backend, you’ll need to use some asynchronous middleware, such as Thunk. If you’re interested, check out this blog post that walks you through setting up Thunk.
Hot tip:
- look up how to use Thunk and maintain access to your Dev tools with {compose} and in general with React
Happy Coding!