【21】前端實習:redux入門學習(核心概念)

【安裝依賴】

npm install --save redux
npm install --save react-redux
npm install --save-dev redux-devtools

【核心概念】

  • state被存放在哪裏?

應用中所有的 state 都以一個對象樹的形式儲存在一個單一的 store 中。

  • 怎麼改變state(state裏面的數據)?

不再直接通過選擇器setter來改變state中的數據。唯一改變 state 的辦法是觸發 action,action 是一個用於描述已發生事件的普通對象, 每個狀態state對應不同的action。

  • action怎麼改變state?

編寫專門的函數來決定每個 action 如何改變應用的 state,這個函數被叫做 reducer

就是這樣!

import { createStore } from 'redux';

/**
 * 這是一個 reducer,形式爲 (state, action) => state 的純函數。
 * 描述了 action 如何把 state 轉變成下一個 state。
 *
 * state 的形式取決於你,可以是基本類型、數組、對象、
 * 甚至是 Immutable.js 生成的數據結構。惟一的要點是
 * 當 state 變化時需要返回全新的對象,而不是修改傳入的參數。
 *
 * 下面例子使用 `switch` 語句和字符串來做判斷,但你可以寫幫助類(helper)
 * 根據不同的約定(如方法映射)來判斷,只要適用你的項目即可。
 */
function counter(state = 0, action) {
  switch (action.type) {
  case 'INCREMENT':
    return state + 1;
  case 'DECREMENT':
    return state - 1;
  default:
    return state;
  }
}

// 創建 Redux store 來存放應用的狀態。
// API 是 { subscribe, dispatch, getState }。
let store = createStore(counter);

// 可以手動訂閱更新,也可以事件綁定到視圖層。
store.subscribe(() =>
  console.log(store.getState())
);

// 改變內部 state 惟一方法是 dispatch 一個 action。
// action 可以被序列化,用日記記錄和儲存下來,後期還可以以回放的方式執行
store.dispatch({ type: 'INCREMENT' });
// 1
store.dispatch({ type: 'INCREMENT' });
// 2
store.dispatch({ type: 'DECREMENT' });
// 1

reducer 只是一個接收 state 和 action,並返回新的 state 的函數。

 

【三大原則】

使用純函數來執行修改

爲了描述 action 如何改變 state tree ,你需要編寫 reducers

Reducer 只是一些純函數,它接收先前的 state 和 action,並返回新的 state。剛開始你可以只有一個 reducer,隨着應用變大,你可以把它拆成多個小的 reducers,分別獨立地操作 state tree 的不同部分,因爲 reducer 只是函數,你可以控制它們被調用的順序,傳入附加數據,甚至編寫可複用的 reducer 來處理一些通用任務,如分頁器。

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.map((todo, index) => {
        if (index === action.index) {
          return Object.assign({}, todo, {
            completed: true
          })
        }
        return todo
      })
    default:
      return state
  }
}

import { combineReducers, createStore } from 'redux'
let reducer = combineReducers({ visibilityFilter, todos })
let store = createStore(reducer)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章