Redux - Actions
Redux - Actions(动作)
Section titled “Redux - Actions(动作)”Actions(动作) 是你的应用向 Redux store(Redux 存储) 发送数据的唯一方式。它们是描述应用中发生的事件的普通 JavaScript 对象,表示要改变 state(状态) 的意图。可以把它们看作是描述发生了什么的事件。
动作对象的核心要求是一个 type(类型) 属性。这个属性通常持有一个字符串,用于唯一标识正在执行的动作类型(例如,‘user/login’, ‘todos/add’, ‘counter/increment’)。
// 示例动作对象{ type: 'todos/addTodo', payload: { id: 1, text: 'Learn Redux', completed: false }}
{ type: 'counter/increment'}
{ type: 'user/updateProfile', payload: { name: 'Jane Doe', email: 'jane.doe@example.com' }}type 属性作为 identifier(标识符),让 reducers(处理器) 知道如何处理该 action。虽然 type 是强制性的,但动作对象的其余结构由你决定。然而,一个常见的约定是将与动作相关的任何数据放在一个 payload(载荷) 字段中。
Action Creators(动作创建者)
Section titled “Action Creators(动作创建者)”在代码中手动创建这些动作对象可能会重复且容易出错。Action Creators(动作创建者) 是创建并返回动作对象的函数。这封装了动作创建逻辑,提高了 consistency(一致性),并使 actions 更易于测试和维护。
简单的 Action Creator 示例:
// 手动定义动作类型常量const ADD_TODO = 'todos/addTodo';
// 动作创建者函数function addTodo(text) { return { type: ADD_TODO, payload: { id: Date.now(), // 生成唯一 ID 的简单方法 text: text, completed: false } };}
// 用法:const action = addTodo('Learn Action Creators');// action 现在是:// { type: 'todos/addTodo', payload: { id: 1678886... , text: 'Learn Action Creators', completed: false } }Dispatching Actions(派发动作)
Section titled “Dispatching Actions(派发动作)”创建 action 或使用 action creator 本身不会改变 state。你需要使用 store.dispatch() 方法将 action 派发 到 Redux store。只有这样,store 才会通过其 reducers 运行该 action 来计算新的 state。
// 假设 'store' 是你配置好的 Redux store
// 直接派发一个动作对象store.dispatch({ type: 'counter/increment' });
// 使用 action creator 派发动作const newTodoText = 'Dispatch actions';store.dispatch(addTodo(newTodoText));在使用 React 等 UI 库的应用中,通常不会直接从 components(组件) 中调用 store.dispatch()。相反,react-redux 等库提供了 helper functions(辅助函数)(例如 useDispatch hook)来在 components 中获取 dispatch 函数。
使用 Redux Toolkit 的 Actions (createSlice)
Section titled “使用 Redux Toolkit 的 Actions (createSlice)”Redux Toolkit 显著减少了与 actions 和 action creators 相关的 boilerplate(样板代码)。它的 createSlice 函数根据你定义的 reducer functions(处理器函数)自动生成 action types 和 action creators。
import { createSlice } from '@reduxjs/toolkit';
const counterSlice = createSlice({ name: 'counter', // 用于生成动作类型前缀('counter/increment') initialState: { value: 0 }, reducers: { // 'increment' 动作的 reducer 函数 increment(state) { state.value += 1; // Immer 在这里允许直接修改 state! }, // 'decrement' 动作的 reducer 函数 decrement(state) { state.value -= 1; }, // 接受 payload 的 reducer 函数 incrementByAmount(state, action) { // action.payload 包含传递给 action creator 的值 state.value += action.payload; } }});
// Action creators 是自动生成的!export const { increment, decrement, incrementByAmount } = counterSlice.actions;
// reducer 函数也自动生成export default counterSlice.reducer;
// 用法:store.dispatch(increment()); // 派发 { type: 'counter/increment' }store.dispatch(decrement()); // 派发 { type: 'counter/decrement' }store.dispatch(incrementByAmount(5)); // 派发 { type: 'counter/incrementByAmount', payload: 5 }如你所见,createSlice 处理 action type 字符串(例如,‘counter/increment’)和相应的 action creator functions(例如,increment())的创建,使整个过程更加简洁且不易出错。