banner
他山之石

他山之石

Redux implementation of a simple counter

title: Implementing a Simple Counter with Redux
date: 2018-02-7 20:37:16
banner: http://img.yanyuanfe.cn/photo-1453928582365-b6ad33cbcf64.jpeg
tags:

  • Redux

Redux focuses on state management and decouples it from React. Redux can also be used with Angular. This article explains how to use Redux with examples to better understand it.

image

Once you have a basic understanding of Redux, you can start using it. Redux focuses on state management and decouples it from React. Redux can also be used with Angular. This article demonstrates how to use Redux in a React application without using react-redux, which helps in understanding the data flow of Redux.

For the complete code, please check out the Github repository: https://github.com/YanYuanFE/redux-app

// clone repo
git clone https://github.com/YanYuanFE/redux-app.git


cd redux-app

// checkout branch
git checkout part-1

// install
npm install

// start
npm start

Getting Started#

First, initialize a React application using create-react-app. Before using it, you need to install it. Open the command line and enter:

npm i create-react-app -g

for global installation. Then, navigate to the directory where you want to develop your application and enter the following command:

create-react-app redux-app

Wait for the creation process to complete. Then, navigate to the newly created directory:

cd redux-app

Run npm start and the React application will automatically run and open in your browser. Next, you need to install Redux by running the following command:

npm i redux --save

Now, you can start writing the Redux part.

Redux#

Since the application is relatively simple, you can directly write the reducer. Create a new folder called "reducers" in the "src" directory, and create a new file called "index.js" inside the "reducers" folder. In the reducer, you mainly handle actions to return a new state. In this application, there are two main actions for the counter: "INCREMENT" and "DECREMENT". When the counter is incremented, the state is increased by 1. When the counter is decremented, the state is decreased by 1. Otherwise, the original state is returned. Export the entire reducer as the default export for other parts to use. The code is as follows:

export default (state = 0, action) => {
  switch (action.type) {
    case 'INCREMENT':
      return state + 1
    case 'DECREMENT':
      return state - 1
    default:
      return state
  }
}

After writing the reducer, the next step is to create a store and inject it into the entire application. To do this, you need to modify the "index.js" file in the "src" directory. Import Redux and use the createStore API provided by Redux to generate the store for the entire application state using the reducer. Pass the store to the root component of the application, App, through props. Also, encapsulate the original rendering logic into a render method and call it manually. Additionally, when the store changes, the application will not automatically re-render. You need to manually subscribe to the store using the store.subscribe(render) method, which means that the store subscribes to the render method and when the store changes, it calls render to re-render the entire application.

ReactDOM.render(<App store={store}/>, document.getElementById('root'))
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import { createStore } from 'redux';
import registerServiceWorker from './registerServiceWorker';
import counter from './reducers';

const store = createStore(counter);

const render = () => ReactDOM.render(<App store={store}/>, document.getElementById('root'));

render();

store.subscribe(render);
registerServiceWorker();

Component Development#

After passing the store to the App component through props, you need to use the store to get data and trigger actions in the App component. In the App component, to separate the logic of the counter, the implementation of the counter will be extracted into a separate component. The App component is responsible for passing data and events to the Counter component through props. Create a new folder called "components" in the "src" directory, and create a new file called "Counter.js" inside the "components" folder. The code for the counter component is as follows:

import React, { Component } from 'react';

class Counter extends Component {
  constructor(props) {
    super(props);
    this.incrementAsync = this.incrementAsync.bind(this);
    this.incrementIfOdd = this.incrementIfOdd.bind(this);
  }

  render() {
    const { value, onIncrement, onDecrement } = this.props;
    return (
      <p>
        Clicked: {value} times
        {' '}
        <button onClick={onIncrement}>
          +
        </button>
        {' '}
        <button onClick={onDecrement}>
          -
        </button>
      </p>
    )
  }
}

export default Counter;

In the Counter component, the value and increment/decrement methods are received from the parent component through props. The value is bound to the view to display the counter value, and the increment and decrement buttons are used to control the increment and decrement operations of the counter. The methods passed from the parent component are bound to the buttons.

Next, in the "App.js" file in the "src" directory, import the Counter component and use it in the render method.

import React, { Component } from 'react';
import Counter from './components/Counter';
import logo from './logo.svg';
import './App.css';

class App extends Component {
  render() {
    const { store } = this.props;

    return (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <h1 className="App-title">Welcome to React</h1>
        </header>
        <p className="App-intro">
          To get started, edit <code>src/App.js</code> and save to reload.
        </p>
        <Counter
          value={store.getState()}
          onIncrement={() => store.dispatch({ type: 'INCREMENT' })}
          onDecrement={() => store.dispatch({ type: 'DECREMENT' })}
        />
      </div>
    );
  }
}

export default App;

In the App component, use ES6 object destructuring syntax to get the store from props. Render the Counter component in the render method and pass the required props to it. The value of the counter is obtained using store.getState(), and the onIncrement and onDecrement methods are passed as props to the Counter component. The onIncrement method dispatches an action with the type 'INCREMENT', and the onDecrement method dispatches an action with the type 'DECREMENT'.

At this point, the entire counter application is fully developed.

npm start

Start the application, open your browser, and you will see the final result:

image

You can click the + and - buttons to control the increment and decrement of the number, and the number is updated in real time.

Conclusion#

The counter application implemented with Redux is now complete. You can try to understand the flow of Redux. Redux's core components include the store, actions, and reducers. The store is exposed to the global application, and through the store, you can get the state, trigger actions, and subscribe to state changes. To change the state data, you must trigger an action. Actions can be triggered by interactions and events. Reducers are used to handle actions and return a new state. When the state changes, the store's subscribe method is triggered, which can be used to update the view. If you are using React to develop your application, as your application becomes more complex, using Redux alone can become cumbersome. You may need to pass the store through props to the components you need. To solve this problem, react-redux was created, which provides a simple way to access the global state. So, stay tuned for that.

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.