SoFunction
Updated on 2025-04-07

Build a simple counter using react and redux

Under the modules folder

Use the createSlice method in the Redux Toolkit to define a Redux state management module. The functions of each part are explained in detail below:

1. Import createSlice

import { createSlice } from "@reduxjs/toolkit";

createSlice is a function provided by the Redux Toolkit to simplify Redux's state management code.

It can generate state, action functions and reducer functions at the same time.

2. Define counterStore

const counterStore = createSlice({
    name: 'counter',
    initialState: {
        count: 0
    },
    reducers: {
        increment(state) {
            ++
        },
        decrement(state) {
            --
        }
    }
})

name attribute

Defines the name of this state as a prefix of the action type.

For example, the generated action types might be counter/increment and counter/decrement.

initialState property

The initial value of the state is defined:

initialState: {
    count: 0
}

Indicates that the state managed by this module is an object containing the count attribute, with an initial value of 0.

reducers attribute

Defines the state modification logic.

The parameters of each function are as follows:

  • state: The current module status.
  • action: Additional information when triggering the function (such as payload).

Here, two reducers are defined:

  • Increase the value of count.
  • UsedImmerThe properties of the state object can be directly modified without returning a new state object.

Decrease the value of count.

3. Deconstruct actions

const { increment, decrement } = ;

createSlice will automatically generate corresponding action creators based on the functions defined in reducers.

is an object containing increment and decrement.

Through deconstruction, two action creators are assigned to increment and decrement respectively.

Example use:

dispatch(increment()); // Trigger increment actiondispatch(decrement()); // Trigger the decrement action

4. Define reducer

const counterReducer = ;

The reducer generated by createSlice is used to register in the Redux store and handle the status updates of the corresponding module.

Here the generated reducer is assigned to the counterReducer.

5. Export actions and reducers

export { increment, decrement };
export default counterReducer;

Export increment and decrement to trigger these actions elsewhere.

The counterReducer is exported by default, used to register in the Redux store.

Summarize

This code defines a simple counter module that contains the following functions:

Initial status: { count: 0 }

Two operations:

  • increment: add count 1.
  • decrement: reduce count by 1.

Automatically generated part:

  • actions: Used to trigger status updates.
  • reducer: handles state update logic.

Its function is to encapsulate counter state management into a separate module for easy integration into the global state of Redux.

Under the store folder

Use the Redux Toolkit to configure the basic structure of the Redux Store and integrate the counterStore module into the Redux Store. The following is a detailed analysis:

1. Import configureStore

import { configureStore } from "@reduxjs/toolkit";

configureStore is a function provided by Redux Toolkit to simplify the process of creating a Redux Store.

Compared to the traditional createStore, configureStore:

Automatically integrates the Redux DevTools extension.

Redux middleware (such as redux-thunk) is automatically configured.

Supports combinations of multiple reducers.

Provides a simpler configuration method.

2. Import counterReducer

import counterReducer from './modules/counterStore';

Import the previously defined counterReducer from the ./modules/counterStore file.

counterReducer is a reducer created by createSlice in counterStore and is used to manage counter state.

3. Configure Store

const store = configureStore({
    reducer: {
        counter: counterReducer
    }
});

Parameters of configureStore

Receives a configuration object that defines the behavior of the Store.

Common configuration items:

reducer:

Defines the reducer for all modules.

Supports combining multiple reducers in object form, similar to traditional Redux's combineReducers.

In this example:

reducer: {
    counter: counterReducer
}

Bind counterReducer to the counter key, which means that the state structure of Redux is as follows:

{
    counter: {
        count: 0
    }
}

4. Export Store

export default store;

Export the created store for use in the app, for example, bind the Store to the React app via Provider.

5. Redux State Tree

According to the configuration, the final Redux state tree is structured as follows:

{
    counter: {
        count: 0
    }
}

counter is the namespace of state, corresponding to counterReducer.

count is a state property in the counter module.

Summarize

This code is a typical way to use the Redux Toolkit:

  • Create a Redux Store using configureStore.
  • Bind counterReducer to the counter namespace.
  • The exported store can be used by React applications through Provider to manage counter state.
  • When expanding other modules, the code structure remains clear and easy to maintain.

Under the src folder

This code shows a typical React project entry file that uses React, React Redux, and Redux Toolkit to set up the application. The following is a detailed analysis part by part:

1. Import React and related libraries

import React from 'react';
import ReactDOM from 'react-dom/client';

React: React's core library for building components and user interfaces.

ReactDOM: React's DOM rendering library for rendering React components into the DOM.

:React 18 New rendering entry method, supporting concurrency features.

2. Import styles and modules

import './';
import App from './App';
import reportWebVitals from './reportWebVitals';
import store from './store';
import { Provider } from 'react-redux';
  • ./: Introduce global style files to define the basic styles of the application.
  • App: The main application component is the root component of the entire React application.
  • reportWebVitals: Performance measurement tool for monitoring and optimizing performance of React applications (optional).
  • store: Import the Redux Store to manage the global state of the application.
  • Provider: From react-redux, used to inject the Redux Store into the entire React component tree.

3. Create a root node

const root = (('root'));

('root'): Select the DOM node in HTML as the mount point of the React application.

: In React 18, use this method to create rendering roots, supporting concurrent rendering features.

4. Render component tree

(
  <>
    <Provider store={store}>
      <App />
    </Provider>
  </>
);

React's debugging tool component, which performs additional checks on the code at runtime:

  • Check whether the use of the life cycle method complies with the specification.
  • Remind possible potential issues (such as unsafe APIs).
  • Enable in development mode will not affect the performance of the production environment.

Provider

The context component provided by Redux is:

  • Pass the store to all child components in the component tree.
  • Any child component that uses useSelector or useDispatch can access Redux's state or distribution actions.
  • The store attribute must be passed in, that is, the created Redux Store instance.

App

  • The root component of the React application, representing the component tree structure of the entire application.
  • Components in the App can access global status through Redux.

5. Performance monitoring

reportWebVitals();

reportWebVitals is a tool provided by create-react-app to monitor performance metrics for React applications.

The parameter is a callback function, which is used to record performance data:

reportWebVitals();

For example, record the loading time of the page, the first content drawing time, etc.

Or, send the data to the analysis server:

reportWebVitals((metric) => {
  sendToAnalytics(metric);
});

6. Apply the overall workflow

A <div >/div> container is defined in HTML as the mount point for the React application.

Create a React root renderer and mount it into the #root container.

Use <Provider> to inject the Redux Store into the entire application, ensuring that child components can manage state through Redux.

Render the main component <App /> and build the user interface.

If performance monitoring is enabled, reportWebVitals captures the performance data of the application.

7. The meaning of code structure

Modular design: Separate style, main components, status management and performance monitoring, clear and easy to expand.

React + Redux: combines Provider to implement global state management, suitable for large applications.

: Help developers catch potential problems and improve code quality.

Summarize

This code completes the basic configuration of a React application, integrates the Redux Store into a React application, and provides performance monitoring capabilities. It is a standard modern React project entry file structure.

Under the src folder

This code shows an example using React and Redux, managing the state of the counter through Redux, and adding and subtracting operations through buttons on the interface. The following is a detailed analysis:

1. Import useDispatch and useSelector

import { useDispatch, useSelector } from "react-redux";
import { increment, decrement } from "./store/modules/counterStore";

useSelector:

React-Redux provides a Hook for selecting status from the Redux Store.

The parameter is a callback function, and the callback's parameter state is the entire state tree of Redux, from which part of the required state can be extracted.

useDispatch:

Another Hook provided by React-Redux is used to distribute Redux actions.

Returns a dispatch function, which will trigger the corresponding reducer update status when called.

increment and decrement:

Action imported from counterStore to update counter status.

2. Define App Components

function App() {
  const { count } = useSelector(state => );
  const dispatch = useDispatch();
  ...
}

useSelector

useSelector(state => ):

Select the status of the counter module from the status tree in Redux.

Corresponding to the status of counter in the Redux Store:

{
  count: 0
}

Deconstruct to get the count value.

useDispatch

useDispatch():

Get the dispatch function.

This function can be used to distribute (dispatch) actions to trigger status updates to Redux.

3. The rendering logic of the component

return (
  <div className="App">
    <button onClick={()=>dispatch(decrement())}>-</button>
    {count}
    <button onClick={()=>dispatch(increment())}>+</button>
  </div>
);

The logic of the button

Minus button

<button onClick={()=>dispatch(decrement())}>-</button>

Call dispatch(decrement()) when clicking:

decrement() is an action defined in counterStore.

Triggers the decrease reducer of counterStore to reduce the count value.

After the status is updated, the React component will be re-rendered and the latest value of count is displayed on the page.

Plus button

<button onClick={()=>dispatch(increment())}>+</button>

Call dispatch(increment()) when clicking:

increment() is an action defined in counterStore.

Trigger the increment reducer of counterStore and increase the count value.

After the status is updated, the React component re-renders to display the latest count value.

Show current count

{count}

Render count value, indicating the status of the current counter.

4. Workflow for Redux state and component interaction

Get status:

  • Use useSelector to extract state from the Redux Store.
  • {count} in the component is automatically updated to reflect the latest status.

Update status:

  • The user clicks the button and triggers the onClick event:
  • dispatch(decrement()) or dispatch(increment()) calls.
  • The distributed action triggers the reducer update status of Redux.
  • The updated state is obtained through useSelector, causing the React component to be rerendered.

5. Combined with the functions of the Redux Store

Assume that the state structure of the Redux Store is as follows:

{
  counter: {
    count: 0
  }
}

Initial status: count = 0

Click the plus button:

  • dispatch(increment())
  • count++, the state becomes { count: 1 }

Click the minus button:

  • dispatch(decrement())
  • count--, the state becomes { count: 0 }

6. The meaning of code

Showcases the integration of React and Redux:

Use useSelector to extract the status.

Use useDispatch to distribute the action.

Dynamic interaction of components is achieved through state management, avoiding the complexity of directly managing state.

The modular Redux Store design makes the code easy to expand, such as adding other state modules or features.

7. Extended suggestions

Add initialization state: The function of initial state can be provided through Redux, making the initial value of count configurable.

Enhanced style: Introduce CSS or component library to beautify buttons and layouts.

Multifunctionality: Add more operations, such as resetting counts, setting the step size of counts.

Summarize

This code is a simple but complete React + Redux example that implements the addition and subtraction of global state count through buttons. It demonstrates the core usage of Redux state management, including useSelector and useDispatch, and seamless integration of Redux and React.

This is the end of this article about using react and redux to build a simple counter. For more related react redux to build counters, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!