How to Create a Simple React Redux App

Advertisement

If you have tried using Redux with React and you are finding it hard to learn. This tutorial is for you.

React Redux without React Redux Toolkit

In this tutorial, we are not going to take advantage of Redux toolkit. I want to keep the project simple so that it can be easy to wrap your mind around all the pieces and how they interact.

Once you understand these pieces, I hope you will be able to use the official React Redux toolkit to manipulate Redux and React to do your bidding.

You can go to Official React Redux docs for the instruction on the official Redux+JS template.

Installation on New Create-React-App(CRA) App

Open your commandline tool or terminal in your prefered folder.

Run the command npx create-react-app simple-react-redux to setup a react app project.

Create react app

Get inside the folder using cd simple-redux-app.

Create react app results

Adding Redux and React-Redux to your React Project

Install the core package of redux.

npm install redux

Since we are going to use redux with react, you will also need to install react-redux package.

npm install react-redux

You can also just combine them into one command.

npm install redux react-redux

Adding React and React Redux to project

You can run npm start to ensure that your react app is running properly.

set up a Redux Store

Inside the src/ folder open the index.js file.

You are going to create the redux store here.

First, you need to import createStore from redux

import {createStore} from 'redux';

Then, you need to create a store.

const store = createStore(counterReducer, initialState);

But the store needs a Redux reducer function so lets create one.

const initialState = { value: 0 };
function counterReducer(state = initialState, action) {
  // Check to see if the reducer cares about this action
  if (action.type === 'counter/incremented') {
    // If so, make a copy of `state`
    return {
      ...state,
      // and update the copy with the new value
      value: state.value + 1
    }
  }
  // otherwise return the existing state unchanged
  return state
}

Now we are going to test if your store is working. First, we are going to send a dispatch that tells the counter to increment. Then we are going to log the store’s state value.

// Simple Dispatch to update state
store.dispatch({
  type: 'counter/incremented',
  text: 'increment by 1'
}) 
// Viewing the store value
console.log(store.getState())

If you inspect the browser’s console tab, you will see the following:

React Redux project console

That means that we have been able to increment the counter value from 0 to 1.

Your index.js file should look like this:

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { createStore } from 'redux';

const initialState = { value: 0 };
function counterReducer(state = initialState, action) {
  // Check to see if the reducer cares about this action
  if (action.type === 'counter/incremented') {
    // If so, make a copy of `state`
    return {
      ...state,
      // and update the copy with the new value
      value: state.value + 1
    }
  }
  // otherwise return the existing state unchanged
  return state
}


// Create Store
const store = createStore(counterReducer, initialState);

// Testing the store
// Simple Dispatch to update state
store.dispatch({
  type: 'counter/incremented',
  text: 'increment by 1'
})
// Viewing the store value
console.log(store.getState())

const root = ReactDOM.createRoot(document.getElementById('root'));

root.render(
  <React.StrictMode>
      <App />
  </React.StrictMode>
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

Adding Redux to React App

Open index.js file. Import Provider from react-redux.

import { Provider } from 'react-redux';

We are then going to pass the store object to the top of the component tree using the Provider component. The store will be available to all components in your project.

root.render(
  <React.StrictMode>
    <Provider store={store}>
      <App />
    </Provider>
  </React.StrictMode>
);

Your index.js file should now have:

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { createStore } from 'redux';
import { Provider } from 'react-redux';

const initialState = { value: 0 };
function counterReducer(state = initialState, action) {
  // Check to see if the reducer cares about this action
  if (action.type === 'counter/incremented') {
    // If so, make a copy of `state`
    return {
      ...state,
      // and update the copy with the new value
      value: state.value + 1
    }
  }
  // otherwise return the existing state unchanged
  return state
}


// Create Store
const store = createStore(counterReducer, initialState);

// Testing the store
// Simple Dispatch to update state
store.dispatch({
  type: 'counter/incremented',
  text: 'increment by 1'
})
// Viewing the store value
console.log(store.getState())

const root = ReactDOM.createRoot(document.getElementById('root'));

root.render(
  <React.StrictMode>
    <Provider store={store}>
      <App />
    </Provider>
  </React.StrictMode>
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

Using Redux with React Hooks Components

Open the app.js file in the src folder. Delete everything in app.js file and add the following code.

function App() {
  return (
    <div>
      <p>Counter Value is: </p>
      <button>Add 1</button>
    </div>
  );
}

export default App;

You should be able to see a button and some text shown below.

React Redux counter component

Reading the Values Stored in Redux using React Hooks

We are going to start by reading the current in the store. react-redux has the useSelector hook that reads the value from the store state and subscribes to updates.

import { useSelector } from 'react-redux';

Then inside the App component:

  const counterstate = useSelector((state)=> state.value);

Now you can read the value:

<p>Counter Value is: { counterstate }</p>

You app.js Code should be:

import { useSelector} from 'react-redux';

function App() {
    const counterstate = useSelector((state)=> state.value);
  return (
    <div>
      <p>Counter Value is: {counterstate}</p>
      <button>Add 1</button>
    </div>
  );
}

export default App;

Changing the Values Stored in Redux using React Hooks

To modify redux store values using Redux, you will use the useDispatch hook provided by react-redux.

import { useSelector, useDispatch } from 'react-redux';

Inside the App component:

const dispatch = useDispatch();

On the button add the dispatch to make changes to the state.

<button onClick={() => dispatch(
    { type: 'counter/incremented', text: 'increment by 1' }
    )}>
  Add 1
</button>

You app.js file should now be:

import { useSelector, useDispatch} from 'react-redux';

function App() {
    const counterstate = useSelector((state)=> state.value);
    const dispatch = useDispatch();

  return (
    <div>
      <p>Counter Value is: {counterstate}</p>
      <button onClick={() => dispatch(
        { type: 'counter/incremented', text: 'increment by 1' }
        )}>
        Add 1
      </button>
    </div>
  );
}

export default App;

React Redux working counter component

author's bio photo

Hi there! I am Avic Ndugu.

I have published 100+ blog posts on HTML, CSS, Javascript, React and other related topics. When I am not writing, I enjoy reading, hiking and listening to podcasts.