banner
他山之石

他山之石

Redux實現簡單計數器

redux 專注於狀態管理,和 react 解耦,redux 也可以結合 Angular 一起使用。本文結合實例講解 Redux 的使用,可以更好的理解 Redux。

image

當你已經了解一些 redux 的基礎概念後,現在開始嘗試使用 redux 吧,redux 專注於狀態管理,和 react 解耦,redux 也可以結合 Angular 一起使用。本文嘗試在 react 應用中使用 redux 來開發應用,而並沒有使用 react-redux,這有助於理解 redux 的數據流。

本文完整代碼請查看 Github: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

開始#

首先,初始化一個 react 應用,使用 creat-react-app 來進行創建,使用之前需要先安裝,打開命令行,輸入:

npm i create-react-app -g

進行全局安裝。然後進入準備開發的目錄,打開命令行,進入當前文件夾,輸入:

create-react-app redux-app

,等待創建完成。然後

cd redux-app

,運行 npm start,react 應用會自動運行並打開瀏覽器。
下一步,需要安裝 redux,命令行輸入

npm i redux --save

,下面,開始編寫 redux 部分。

redux#

由於應用比較簡單,可以直接編寫 reducer 部分,在 src 目錄下新建 reducers 文件夾,新建 index.js,在 reducer 中,主要處理 action 來返回新的 state,在本應用中,計數器觸發的 action 主要有加和減兩種,分別將其定義為
'INCREMENT' 和 'DECREMENT',當觸發計數器加 1 的時候,將 state+1, 觸發計數器減 1 的時候,將 state-1, 否則,將返回原來的 satte。並且需要將整個 reducer export default 以供其他部分使用。代碼如下:

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

reducer 編寫完畢後,下一步需要生成 store 注入整個應用。此處,需要修改 src 目錄下的 index.js,通過 import 導入 redux,需要使用 redux 提供的 APIcreateStore 將 reducer 生成整個應用的狀態 store,並且將 store 通過 props 傳入整個應用的根組件 App。同時,需要將原本的渲染邏輯封裝成一個 render 方法並手動調用。同時,當 store 改變後,應用並不會自動重新渲染,需要使用 store 的方法 subscribe 來手動訂閱,store.subscribe (render); 意思是讓 store 訂閱 render 方法,當 store 改變時,就調用 render 重新渲染整個應用。

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();

組件編寫#

store 通過 props 傳遞到 APP 組件後,在 APP 組件內需要通過 store 來獲取數據以及觸發 action。在 APP 組件中,為了使組件邏輯分離,計數器相關的實現將會單獨抽離成組件,APP 組件負責將數據和事件通過 props 傳遞到計數器組件中。
在 src 目錄下新建 components 目錄,在 components 目錄下新建 Counter.js,下面是計數器的代碼:

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;

在 Counter 組件中,通過 props 接收父組件傳遞的 value 和加、減數值的方法,value 綁定到視圖顯示計數器的數值,加、減按鈕分別用來控制計數器的加減操作,分別將父組件傳遞的方法進行綁定到按鈕上。
然後在 src 目錄下的 App.js 中引入計數器的組件,並在 render 中使用。

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;

在 APP 組件中,使用 ES6 的對象解構語法在 props 中獲取 store,在 render 中渲染計數器組件 Counter,同時,向 Couter 組件傳入約定的 props,計數器數值 value 通過 store.getState () 來獲取,增加數值方法 onIncrement 傳入一個方法,調用 store.dispatch 來發起一個 Action,action 中傳入代表增加數值的 type ‘Increment’,同理,減少數值的方法 onDecrement 中傳入的 actionType 為‘DECREMENT’。

到這裡,整個計數器應用就完全開發完成了。

npm start

啟動應用,打開瀏覽器,最終效果如下:

image

點擊 +、- 按鈕可以控制數字的加減,而且數字是實時更新的。

寫在最後#

通過 redux 實現的計數器應用已經開發完成了,你可以嘗試梳理一下 redux 的流程,首先,redux 的核心包括 store、action、reducer,store 暴露到全局應用中,通過 store 可以獲取 state,觸發 action,訂閱 state 改變後的事件。要想改變 state 的數據,必須觸發 Action,action 可以通過一些交互和事件來觸發,reducer 用來處理 action,並返回一個新的 state,當 state 改變後,store 的 subscribe 方法就會觸發,可以用來更新視圖。如果你使用 react 來開發應用,當你的應用變得複雜,僅僅使用 redux 會變得很繁瑣,你可能需要將 store 通過 props 來一層層傳遞到你需要的組件中,為了解決這樣的問題,react-redux 出現了,可以使用簡單的方式獲取到全局的狀態,那麼,拭目以待吧。

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。