博主头像
<CodeEra />

心存敬畏 行有所止

Redux 工程化:Action Creator 的创建

基本概念

Action Creator 是一个函数,它创建并返回一个 action 对象。使用 Action Creator 可以带来以下好处:

  • 集中管理 action 类型
  • 减少手动编写 action 对象时的错误
  • 便于处理异步操作
  • 提高代码可维护性

基础 Action Creator

// 基础形式
function addTodo(text) {
  return {
    type: 'ADD_TODO',
    payload: {
      text,
      id: Date.now(),
      completed: false
    }
  };
}

工程化实践

1. 常量管理 Action 类型

// actionTypes.js
export const ADD_TODO = 'ADD_TODO';
export const TOGGLE_TODO = 'TOGGLE_TODO';
export const DELETE_TODO = 'DELETE_TODO';

// actions.js
import { ADD_TODO, TOGGLE_TODO, DELETE_TODO } from './actionTypes';

export const addTodo = (text) => ({
  type: ADD_TODO,
  payload: { text, id: Date.now(), completed: false }
});

export const toggleTodo = (id) => ({
  type: TOGGLE_TODO,
  payload: { id }
});

export const deleteTodo = (id) => ({
  type: DELETE_TODO,
  payload: { id }
});

2. 使用 payload 规范

推荐使用 Flux Standard Action (FSA) 规范:

  • type: 必须的字符串
  • payload: 可选的数据
  • error: 可选的布尔值,表示是否是错误
  • meta: 可选的额外信息

3. 异步 Action Creator

对于异步操作,可以使用 Redux Thunk 或 Redux Saga 等中间件:

// 使用 Redux Thunk
export const fetchTodos = () => {
  return async (dispatch) => {
    dispatch({ type: 'FETCH_TODOS_REQUEST' });
    
    try {
      const response = await api.getTodos();
      dispatch({
        type: 'FETCH_TODOS_SUCCESS',
        payload: response.data
      });
    } catch (error) {
      dispatch({
        type: 'FETCH_TODOS_FAILURE',
        payload: error,
        error: true
      });
    }
  };
};

4. Action Creator 工厂函数

对于相似的 action,可以创建工厂函数:

const createAsyncActions = (type) => {
  return {
    request: (payload) => ({ type: `${type}_REQUEST`, payload }),
    success: (payload) => ({ type: `${type}_SUCCESS`, payload }),
    failure: (error) => ({ type: `${type}_FAILURE`, payload: error, error: true })
  };
};

// 使用
const todoActions = createAsyncActions('TODO');
// todoActions.request(), todoActions.success(), todoActions.failure()

5. 使用 redux-actions 库

redux-actions 提供了 createActionhandleActions 等实用函数:

import { createAction } from 'redux-actions';

export const addTodo = createAction('ADD_TODO', text => ({
  text,
  id: Date.now(),
  completed: false
}));

// 使用
dispatch(addTodo('Learn Redux'));

最佳实践

  1. 命名规范:使用全大写和下划线命名 action 类型,如 FETCH_USER_SUCCESS
  2. 单一职责:每个 action creator 只做一件事
  3. 纯函数:确保 action creator 是纯函数,不产生副作用
  4. 文档注释:为每个 action creator 添加清晰的注释
  5. 测试:为 action creator 编写单元测试

目录结构建议

store/
  actions/
    index.js          // 导出所有 action creator
    todoAction.js    // todo 相关的 action
    userAction.js    // 用户相关的 action
  reducers/
    index.js          
    todoReducer.js    // todo 相关的 action
    userReducer.js    // 用户相关的 action
  actionTypes.js    // 所有 action 类型常量
  index.js

命名导出及使用方式

// actions/index.js

// 从各个模块导入 action creators
import * as todoActions from './todoActions';
import * as userActions from './userActions';
import * as productActions from './productActions';

// 集中导出所有 action creators
export {
  todoActions,
  userActions,
  productActions
};

// 也可以选择平铺导出(根据项目规模决定)
export * from './todoActions';
export * from './userActions';
export * from './productActions';

// 在组件中使用------------------------------------

// 使用命名空间方式
import { todoActions, userActions } from '../actions';

dispatch(todoActions.addTodo('Learn Redux'));
dispatch(userActions.login({ username: 'test', password: '123' }));

// 使用平铺导出方式
import { addTodo, login } from '../actions';

dispatch(addTodo('Learn Redux'));
dispatch(login({ username: 'test', password: '123' }));
已有 5 条评论
  1. 评论头像

    新盘新项目,不再等待,现在就是最佳上车机会!

    xehrzqaxib October 5th, 2025 at 05:06 am 回复
  2. 评论头像

    新车上路,只带前10个人coinsrore.com

    btwueubpab October 5th, 2025 at 05:18 am 回复
  3. 评论头像

    2025年10月新盘 做第一批吃螃蟹的人coinsrore.com
    新车新盘 嘎嘎稳 嘎嘎靠谱coinsrore.com
    新车首发,新的一年,只带想赚米的人coinsrore.com
    新盘 上车集合 留下 我要发发 立马进裙coinsrore.com
    做了几十年的项目 我总结了最好的一个盘(纯干货)coinsrore.com
    新车上路,只带前10个人coinsrore.com
    新盘首开 新盘首开 征召客户!!!coinsrore.com
    新项目准备上线,寻找志同道合的合作伙伴coinsrore.com
    新车即将上线 真正的项目,期待你的参与coinsrore.com
    新盘新项目,不再等待,现在就是最佳上车机会!coinsrore.com
    新盘新盘 这个月刚上新盘 新车第一个吃螃蟹!coinsrore.com

    ctrkdnowja October 7th, 2025 at 11:06 am 回复
  4. 评论头像

    华纳公司合作开户所需材料?电话号码15587291507 微信STS5099
    华纳公司合作开户所需材料?电话号码15587291507 微信STS5099
    华纳公司合作开户所需材料?电话号码15587291507 微信STS5099
    华纳公司合作开户所需材料?电话号码15587291507 微信STS5099
    华纳公司合作开户所需材料?电话号码15587291507 微信STS5099
    华纳公司合作开户所需材料?电话号码15587291507 微信STS5099
    华纳公司合作开户所需材料?电话号码15587291507 微信STS5099
    华纳公司合作开户所需材料?电话号码15587291507 微信STS5099

  5. 评论头像

    华纳东方明珠客服电话是多少?(▲18288362750?《?微信STS5099? 】
    如何联系华纳东方明珠客服?(▲18288362750?《?微信STS5099? 】
    华纳东方明珠官方客服联系方式?(▲18288362750?《?微信STS5099?
    华纳东方明珠客服热线?(▲18288362750?《?微信STS5099?
    华纳东方明珠24小时客服电话?(▲18288362750?《?微信STS5099? 】
    华纳东方明珠官方客服在线咨询?(▲18288362750?《?微信STS5099?

发表新评论