redux簡單使用

Jokcy發表於2016-03-15

在react火熱的年代,flux作為fb提出的最適合react的資料模型,時下有非常多的實現。
而redux作為在眾多的flux地實現中脫穎而出,及其精簡的程式碼,卻能帶來實用的功能,正好自己的專案中要用,所以讓我們來分析redux

為什麼要寫這個文件呢,因為我看官方文件各種看不懂啊,琢磨了半天都不理解,最後是去看了原始碼才看明白
因為他的一些概念沒搞清楚的話,就不知道他的文件在說什麼。為了不讓更多的人掉坑裡面,這裡稍微解釋一些概念。

學習redux需要知道redux的三個部分:

  1. action

  2. reducer

  3. store

action

redux中得action就是你自己定義的一個動作,什麼是動作?你可以理解為使用者的動作你做出的反應,最簡單地例子就是當你進行分頁的時候,
跳到特定的頁數這個動作。我們可以通過類似如下的程式碼定義action:

/*
 * action types
 */
 
export const ADD_TODO = `ADD_TODO`;
export const COMPLETE_TODO = `COMPLETE_TODO`;
export const SET_VISIBILITY_FILTER = `SET_VISIBILITY_FILTER`;

/*
 * other constants
 */

export const VisibilityFilters = {
  SHOW_ALL: `SHOW_ALL`,
  SHOW_COMPLETED: `SHOW_COMPLETED`,
  SHOW_ACTIVE: `SHOW_ACTIVE`
};

/*
 * action creators
 */

export function addTodo(text) {
  return { type: ADD_TODO, text };
}

export function completeTodo(index) {
  return { type: COMPLETE_TODO, index };
}

export function setVisibilityFilter(filter) {
  return { type: SET_VISIBILITY_FILTER, filter };
}

在這裡定義action之後用來出發的,通過dispatch方法來觸發動作,在這裡action只是一些常亮的定義。
dispatch方法接收的引數是一個object,而且object必須包含一個type屬性,告訴我們需要執行的操作。
而物件裡面的包含的其他屬性則可以在執行動作的時候用作其他用途。

dispatch方法是會在store連線元件的時候隨著元件的props傳遞到各個元件的,所以元件內都是可以用的。

reducer

這是在redux裡面提出來的概念,具體啥含義請參考官網,因為我也解釋不清楚╮(╯▽╰)╭

reducer在這裡是核心,因為redux是隻有一個store的,所以整個app的狀態和資料都儲存在一個store裡面,
如果所有狀態變化都在store裡面進行邏輯操作,那麼這個store肯定是無法維護的,所以在這裡我們把狀態的變化放到了reducer裡面。
我們先來看一下如何定義一個reducer:

import { combineReducers } from `redux`;
import { ADD_TODO, COMPLETE_TODO, SET_VISIBILITY_FILTER, VisibilityFilters } from `./actions`;
const { SHOW_ALL } = VisibilityFilters;

function visibilityFilter(state = SHOW_ALL, action) {
  switch (action.type) {
  case SET_VISIBILITY_FILTER:
    return action.filter;
  default:
    return state;
  }
}

function todos(state = [], action) {
  switch (action.type) {
  case ADD_TODO:
    return [...state, {
      text: action.text,
      completed: false
    }];
  case COMPLETE_TODO:
    return [
      ...state.slice(0, action.index),
      Object.assign({}, state[action.index], {
        completed: true
      }),
      ...state.slice(action.index + 1)
    ];
  default:
    return state;
  }
}

const todoApp = combineReducers({
  visibilityFilter,
  todos
});

export default todoApp;

如你所見,reducer只是一個方法,在reducer裡面根據傳入的action裡面的type進行不同的state地操作。
在這裡必須理解一點,在你呼叫dispatch方法的時候傳入的action動作就是reducer裡面接受的action

在這裡我們唯一用到redux的功能只有combineReducers方法,這個方法的作用是把不同的reducer合併到一起,
因為在建立store的時候我們只能傳入一個reducer,但是我們不可能把所有邏輯操作寫到一個reducer裡面,所以這邊提供了這個方法。

store

store的作用即是整合所有的reducer,然後提供一些幫助方法,例如dispatch等方法讓我們使用,
程式碼如下:

let store = createStore(reducer);

是的,就是這麼簡單。

如何跟react一起使用

請參考文件
這邊並不進行詳細講解,以為這不是這篇文章的重點,以後會單獨在其他文章中進行講解。

理解

如何理解redux的重點就在於,redux如何處理整個資料流的走向。
基本的思路如下:

component --dispatch(action)--> reducer --update(state)--> store --update(props)--> component

這就是整個資料的走向

看到這裡,你們肯定跟我有相同的想法:reducer到底是個什麼東西!

那麼我們就來理解一下

我們看一下reducer的定義:

function todos(state = [], action) {
  switch (action.type) {
  case ADD_TODO:
    return [...state, {
      text: action.text,
      completed: false
    }];
  case COMPLETE_TODO:
    return [
      ...state.slice(0, action.index),
      Object.assign({}, state[action.index], {
        completed: true
      }),
      ...state.slice(action.index + 1)
    ];
  default:
    return state;
  }
}

首先他接受兩個引數,一個是state,一個是action。

action我們知道是在dispatch的時候傳入的告訴我們進行什麼操作的,那麼state是什麼?
state就是store裡面存著的狀態,即資料。我們可以看到每個reducer都會返回state,而這些state最終都會儲存在store裡面。

**每次觸發一個action的時候,store呼叫reducer,同時傳入本身儲存著的state,reducer根據傳入的state和action返回新的state,
store更新state,返回以props的方式傳入元件,這就形成了整個資料流迴圈**

以上是redux的最基礎使用,這也是redux的核心,然後後面還有一堆redux的擴充套件以及中介軟體進行學習,這僅僅是一個開始,以後還有更長的路要走^_^

相關文章