Redux Action

2021-09-16 09:50 更新

Action

首先,讓我們來給 action 下個定義。

Actions 是把數(shù)據(jù)從應(yīng)用(譯者注:這里之所以不叫 view 是因為這些數(shù)據(jù)有可能是服務(wù)器響應(yīng),用戶輸入或其它非 view 的數(shù)據(jù) )傳到 store 的有效載荷。它是 store 數(shù)據(jù)的惟一來源。用法是通過 store.dispatch() 把 action 傳到 store。

添加新 todo 任務(wù)的 action 是這樣的:

const ADD_TODO = 'ADD_TODO';
{
  type: 'ADD_TODO',
  text: 'Build my first Redux app'
}

Action 本質(zhì)是 JavaScript 普通對象。我們約定,action 內(nèi)使用一個字符串類型的 type 字段來表示將要執(zhí)行的動作。多數(shù)情況下,type 會被定義成字符串常量。當應(yīng)用規(guī)模越來越大時,建議使用單獨的模塊或文件來存放 action。

import { ADD_TODO, REMOVE_TODO } from '../actionTypes';
樣板文件使用提醒

使用單獨的模塊或文件來定義 action type 常量并不是必須的,甚至根本不需要定義。對于小應(yīng)用來說,使用字符串做 action type 更方便些。不過,在大型應(yīng)用中最多把它們顯式地定義成常量。參照 減少樣板代碼 獲取保持代碼干凈的實踐經(jīng)驗。

除了 type 字段外,action 對象的結(jié)構(gòu)完全取決于你。參照 Flux 標準 Action 獲取如何組織 action 的建議。

這時,我們還需要再添加一個 action type 來標記任務(wù)完成。因為數(shù)據(jù)是存放在數(shù)組中的,我們通過 index 來標識任務(wù)。實際項目中一般會在新建內(nèi)容的時候生成惟一的 ID 做標識。

{
  type: COMPLETE_TODO,
  index: 5
}

action 中傳遞的數(shù)據(jù)越少越好。比如,這里傳遞 index 就比把整個任務(wù)對象傳過去要好。

最后,再添加一個 action 類型來表示當前展示的任務(wù)狀態(tài)。

{
  type: SET_VISIBILITY_FILTER,
  filter: SHOW_COMPLETED
}

Action 創(chuàng)建函數(shù)

Action 創(chuàng)建函數(shù) 就是生成 action 的方法?!癮ction” 和 “action 創(chuàng)建函數(shù)” 這兩個概念很容易混在一起,使用時最好注意區(qū)分。

傳統(tǒng)的 Flux 實現(xiàn)中,當調(diào)用 action 創(chuàng)建函數(shù)時,一般會觸發(fā)一個 dispatch,像這樣:

function addTodoWithDispatch(text) {
  const action = {
    type: ADD_TODO,
    text
  };
  dispatch(action);
}

不同的是,Redux 中的 action 創(chuàng)建函數(shù)是 純函數(shù),它沒有任何副作用,只是返回 action 對象而已。

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

這讓代碼更易于測試和移植。只需把 action 創(chuàng)建函數(shù)的結(jié)果傳給 dispatch() 方法即可實例化 dispatch。

dispatch(addTodo(text));
dispatch(completeTodo(index));

或者創(chuàng)建一個 被綁定的 action 創(chuàng)建函數(shù) 來自動 dispatch:

const boundAddTodo = (text) => dispatch(addTodo(text));
const boundCompleteTodo = (index) => dispatch(CompleteTodo(index));

可以這樣調(diào)用:

boundAddTodo(text);
boundCompleteTodo(index);

store 里能直接通過 store.dispatch() 調(diào)用 dispatch() 方法,但是多數(shù)情況下你會使用 react-redux 提供的 connect() 幫助器來調(diào)用。bindActionCreators() 可以自動把多個 action 創(chuàng)建函數(shù) 綁定到 dispatch() 方法上。

源碼

actions.js

/*
 * action 類型
 */

export const ADD_TODO = 'ADD_TODO';
export const COMPLETE_TODO = 'COMPLETE_TODO';
export const SET_VISIBILITY_FILTER = 'SET_VISIBILITY_FILTER';

/*
 * 其它的常量
 */

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

/*
 * action 創(chuàng)建函數(shù)
 */

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 };
}

下一步

現(xiàn)在讓我們 開發(fā)一些 reducers 來指定發(fā)起 action 后 state 應(yīng)該如何更新。

高級用戶建議

如果你已經(jīng)熟悉這些基本概念且已經(jīng)完成了這個示例,不要忘了看一下在 高級教程 中的 異步 actions,你將學(xué)習如何處理 AJAX 響應(yīng)和如何把 action 創(chuàng)建函數(shù)組合成異步控制流。

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號