redux用法总结

121 阅读3分钟

redux用法总结

目录

  1. 基本概念
  2. 工作原理
  3. 核心概念
  4. 基本使用
  5. 异步操作
  6. React 集成
  7. Redux Toolkit
  8. 最佳实践

基本概念

什么是 Redux?

Redux 是一个可预测的状态容器,用于管理 JavaScript 应用的状态。它遵循三个基本原则:

  • 单一数据源:整个应用的状态存储在单个 store 中
  • 状态是只读的:唯一改变状态的方式是触发 action
  • 使用纯函数进行修改:使用 reducer 来指定状态如何更新

核心概念图

Action --> Dispatcher --> Store --> View
   ^                                |
   |                                |
   +--------------------------------+

在这里插入图片描述

工作原理

1. 基本流程

// 1. 创建 action
const addTodo = (text: string) => ({
  type: 'ADD_TODO',
  payload: text
});

// 2. Reducer 处理 action
const todoReducer = (state = [], action) => {
  switch (action.type) {
    case 'ADD_TODO':
      return [...state, action.payload];
    default:
      return state;
  }
};

// 3. 创建 store
const store = createStore(todoReducer);

// 4. 订阅变化
store.subscribe(() => {
  console.log('State updated:', store.getState());
});

// 5. 发送 action
store.dispatch(addTodo('Learn Redux'));

核心概念

1. Action

// Action 类型定义
interface Action {
  type: string;
  payload?: any;
}

// Action Creator
const increment = (amount: number): Action => ({
  type: 'INCREMENT',
  payload: amount
});

2. Reducer

// 基本 reducer
const counterReducer = (state = 0, action: ActionType) => {
  switch (action.type) {
    case 'INCREMENT':
      return state + action.payload;
    case 'DECREMENT':
      return state - action.payload;
    default:
      return state;
  }
};

// 组合 reducers
const rootReducer = combineReducers({
  counter: counterReducer,
  todos: todosReducer
});

3. Store

// 创建 store
const store = createStore(rootReducer);

// 获取状态
console.log(store.getState());

// 订阅变化
const unsubscribe = store.subscribe(() => {
  console.log('State updated:', store.getState());
});

// 发送 action
store.dispatch(increment(5));

异步操作

1. Redux Thunk

// actions/userActions.ts
import { Dispatch } from 'redux';

export const fetchUser = (id: string) => {
  return async (dispatch: Dispatch) => {
    dispatch({ type: 'FETCH_USER_REQUEST' });
    
    try {
      const response = await fetch(`/api/users/${id}`);
      const data = await response.json();
      dispatch({ type: 'FETCH_USER_SUCCESS', payload: data });
    } catch (error) {
      dispatch({ type: 'FETCH_USER_FAILURE', payload: error.message });
    }
  };
};

2. Redux Saga

2.1 基本概念

Redux Saga 是一个用于处理副作用的中间件,使用 ES6 的 Generator 函数。

2.2 核心 Effect Creators
  • take: 等待指定 action 被触发
  • put: 触发一个新的 action
  • call: 调用异步函数
  • fork: 非阻塞调用
  • select: 获取 state 数据
  • takeLatest: 只执行最新的调用
  • takeEvery: 执行每一次调用
  • all: 并行执行
  • race: 竞态处理
2.3 基本配置
// 配置 Saga 中间件
import createSagaMiddleware from 'redux-saga';
import rootSaga from './sagas';

const sagaMiddleware = createSagaMiddleware();

const store = createStore(
  rootReducer,
  applyMiddleware(sagaMiddleware)
);

sagaMiddleware.run(rootSaga);
2.4 常见使用场景
  1. API 请求处理
function* fetchUserSaga(action) {
  try {
    const user = yield call(api.fetchUser, action.payload);
    yield put({ type: 'FETCH_USER_SUCCESS', payload: user });
  } catch (error) {
    yield put({ type: 'FETCH_USER_FAILURE', error });
  }
}

function* watchFetchUser() {
  yield takeLatest('FETCH_USER_REQUEST', fetchUserSaga);
}
  1. 并发控制
function* fetchAll() {
  const [users, posts] = yield all([
    call(api.fetchUsers),
    call(api.fetchPosts)
  ]);
  
  yield put({ type: 'FETCH_ALL_SUCCESS', payload: { users, posts } });
}
  1. 轮询
function* pollData() {
  while (true) {
    try {
      const data = yield call(api.fetchData);
      yield put({ type: 'POLL_SUCCESS', payload: data });
      yield delay(5000);
    } catch (error) {
      yield put({ type: 'POLL_FAILURE', error });
    }
  }
}
  1. 取消操作
function* fetchWithCancel() {
  const bgTask = yield fork(backgroundTask);
  yield take('CANCEL_FETCH');
  yield cancel(bgTask);
}
2.5 适用场景
  1. 适合使用 Saga 的场景:

    • 复杂的异步流程控制
    • 需要取消的操作
    • 并发控制
    • API 调用序列
    • 实时数据处理
    • 复杂的状态同步
  2. 不适合使用 Saga 的场景:

    • 简单的异步操作
    • 同步操作
    • 单一的 API 调用

React 集成

1. 使用 React-Redux

// App.tsx
import { Provider } from 'react-redux';
import store from './store';

function App() {
  return (
    <Provider store={store}>
      <TodoList />
    </Provider>
  );
}

// components/TodoList.tsx
import { useSelector, useDispatch } from 'react-redux';

function TodoList() {
  const todos = useSelector(state => state.todos);
  const dispatch = useDispatch();
  
  return (
    // JSX
  );
}

Redux Toolkit

1. 创建 Slice

import { createSlice } from '@reduxjs/toolkit';

const counterSlice = createSlice({
  name: 'counter',
  initialState: { value: 0 },
  reducers: {
    increment: state => {
      state.value += 1;
    },
    decrement: state => {
      state.value -= 1;
    }
  }
});

export const { increment, decrement } = counterSlice.actions;
export default counterSlice.reducer;

最佳实践

  1. 状态设计:

    • 保持状态扁平化
    • 避免冗余数据
    • 使用规范化的数据结构
  2. Action 设计:

    • 使用动作创建器
    • 保持 action 简单
    • 使用类型常量
  3. 异步处理:

    • 简单异步用 Thunk
    • 复杂异步用 Saga
    • 合理使用中间件
  4. 性能优化:

    • 使用选择器模式
    • 避免不必要的渲染
    • 合理使用缓存

总结

  1. Redux 优点:

    • 可预测的状态管理
    • 集中的状态管理
    • 易于调试
    • 强大的中间件生态
  2. 使用场景:

    • 大型应用
    • 复杂的状态逻辑
    • 多人协作项目
    • 需要状态持久化
  3. 最佳实践:

    • 使用 TypeScript
    • 采用 Redux Toolkit
    • 实现状态范式化
    • 使用选择器模式