Redux 中异步请求数据时发送多 Action 方法

Redux 中异步请求数据时发送多 Action 的方法有以下几种:

  • 使用 Redux Thunk 中间件,它可以让你在 Redux Store 中分发一个函数,而不是一个对象。这个函数可以接收 dispatch 和 getState 作为参数,并在函数内部执行异步操作,然后根据异步操作的结果分发不同的 Action。
  • 使用 Redux Saga 中间件,它可以让你在 Redux Store 中分发一个特殊的 Action,称为 Saga Action。这个 Action 会被 Redux Saga 捕获,并执行一个生成器函数,称为 Saga。Saga 可以使用一些特殊的指令,称为 Effect,来执行异步操作,并根据异步操作的结果分发不同的 Action。
  • 使用 Redux Toolkit 库提供的 createAsyncThunk 函数,它可以让你创建一个特殊的 Action 创建器,称为 Thunk Action 创建器。这个创建器会返回一个 Thunk Action,即一个带有 payloadCreator 和 typePrefix 属性的函数。当这个 Thunk Action 被分发时,它会执行 payloadCreator 函数,并根据 payloadCreator 函数的返回值(通常是一个 Promise)分发不同的 Action,这些 Action 的类型都会带有 typePrefix 前缀。
  • Redux-Thunk 和 Redux-Saga 结合 有时我们可以将 Redux-Thunk 和 Redux-Saga 结合使用。可以使用 Redux-Thunk 来处理一些简单的异步操作,而使用 Redux-Saga 来处理复杂的异步操作,或者在项目中逐步迁移到 Redux-Saga。

以下是一些示例代码:

  • 使用 Redux Thunk 中间件:
// action types
const FETCH_TODOS_REQUEST = 'FETCH_TODOS_REQUEST';
const FETCH_TODOS_SUCCESS = 'FETCH_TODOS_SUCCESS';
const FETCH_TODOS_FAILURE = 'FETCH_TODOS_FAILURE';

// action creators
const fetchTodosRequest = () => ({ type: FETCH_TODOS_REQUEST });
const fetchTodosSuccess = todos => ({ type: FETCH_TODOS_SUCCESS, payload: todos });
const fetchTodosFailure = error => ({ type: FETCH_TODOS_FAILURE, payload: error });

// thunk action creator
const fetchTodos = () => async (dispatch, getState) => {
  dispatch(fetchTodosRequest());
  try {
    const response = await fetch('/api/todos');
    const todos = await response.json();
    dispatch(fetchTodosSuccess(todos));
  } catch (error) {
    dispatch(fetchTodosFailure(error));
  }
};

// reducer
const initialState = {
  loading: false,
  data: [],
  error: null,
};

const todosReducer = (state = initialState, action) => {
  switch (action.type) {
    case FETCH_TODOS_REQUEST:
      return { ...state, loading: true };
    case FETCH_TODOS_SUCCESS:
      return { ...state, loading: false, data: action.payload };
    case FETCH_TODOS_FAILURE:
      return { ...state, loading: false, error: action.payload };
    default:
      return state;
  }
};

  • 使用 Redux Saga 中间件:
// action types
const FETCH_TODOS_REQUEST = 'FETCH_TODOS_REQUEST';
const FETCH_TODOS_SUCCESS = 'FETCH_TODOS_SUCCESS';
const FETCH_TODOS_FAILURE = 'FETCH_TODOS_FAILURE';

// action creators
const fetchTodosRequest = () => ({ type: FETCH_TODOS_REQUEST });
const fetchTodosSuccess = todos => ({ type: FETCH_TODOS_SUCCESS, payload: todos });
const fetchTodosFailure = error => ({ type: FETCH_TODOS_FAILURE, payload: error });

// saga action creator
const fetchTodosSaga = () => ({ type: 'FETCH_TODOS_SAGA' });

// saga
function* fetchTodos() {
  try {
    const response = yield call(fetch, '/api/todos');
    const todos = yield call([response, 'json']);
    yield put(fetchTodosSuccess(todos));
  } catch (error) {
    yield put(fetchTodosFailure(error));
  }
}

// root saga
function* rootSaga() {
  yield takeEvery('FETCH_TODOS_SAGA', fetchTodos);
}

// reducer
const initialState = {
  loading: false,
  data: [],
  error: null,
};

const todosReducer = (state = initialState, action) => {
  switch (action.type) {
    case FETCH_TODOS_REQUEST:
      return { ...state, loading: true };
    case FETCH_TODOS_SUCCESS:
      return { ...state, loading: false, data: action.payload };
    case FETCH_TODOS_FAILURE:
      return { ...state, loading: false, error: action.payload };
    default:
      return state;
  }
};

  • 使用 Redux Toolkit 库提供的 createAsyncThunk 函数:
import { createAsyncThunk, createSlice } from '@reduxjs/toolkit';

// thunk action creator
const fetchTodos = createAsyncThunk(
  'todos/fetchTodos',
  async () => {
    const response = await fetch('/api/todos');
    const todos = await response.json();
    return todos;
  }
);

// slice
const todosSlice = createSlice({
  name: 'todos',
  initialState: {
    loading: false,
    data: [],
    error: null,
  },
  reducers: {},
  extraReducers: {
    [fetchTodos.pending]: (state, action) => {
      state.loading = true;
    },
    [fetchTodos.fulfilled]: (state, action) => {
      state.loading = false;
      state.data = action.payload;
    },
    [fetchTodos.rejected]: (state, action) => {
      state.loading = false;
      state.error = action.error;
    },
  },
});

// reducer
const todosReducer = todosSlice.reducer;

  • Redux-Thunk 和 Redux-Saga 结合 有时我们可以将 Redux-Thunk 和 Redux-Saga 结合使用。可以使用 Redux-Thunk 来处理一些简单的异步操作,而使用 Redux-Saga 来处理复杂的异步操作,或者在项目中逐步迁移到 Redux-Saga。
全部评论

相关推荐

时间线: 1.4-1.5: boss 牛客 官网 实习僧海投了两天, 感觉确实没啥招人的啊, 心里凉了一半.1.6: 中午快手约面, 下午字节hr飞书私聊约面, 当时想着第一次面大厂感觉三个过一个一面就已经赢了.1.7: 下午 3点大厂处女面, 哈哈面试官是重邮红岩的直接保送; 5点快手一面, 我说这个是我的第二次大厂面试, 面试官问要是拿到字节和快手选择哪个, 我说昨天看了一晚上快手百分百选快手哈哈哈. 晚上5.30字节约二面, 快手约二面, 小红书约一面.1.8: 下午2点快手二面, 聊天面体验非常好(当天电话确认入职时间); 4点字节二面这次不是校友了, 然后有一个CSS实现switch效果的忘记属性咋写了, 感觉危了; 7.30 问字节hr是不是挂了; 9点开始小红书一面, 难死我了, 但我还是笑着面完了, 然后卸载了小红书, 但是过了一会会小红书hr约二面, 遂下回来了字节约三面.1.9: 下午2点字节三面, 依旧聊天+算法, 自己太菜了有一个写错了, 面完感觉又危了; 5点面小红书20min结束(offer审批);5.30又去问字节hr是不是挂了, hr小姐姐说干嘛用一个句式, 我说手写题又又又没写出来😂, 2min后约hr面;8.30 快手offer总结, 自己运气好遇到了好公司好部门好面试官, 字节剪映 快手电商 小红书支付的面试体验都非常好, 不会的题会带你一步一步思考, 流程也非常快全部都是当天推进, 小红书是以分钟为单位推进.  面经以及细节等我慢慢整理,  以及保佑所有的审批不要出问题, 我是真怕最后全过了0offer😂bg: 重邮 大数据 蓝山工作室 一段非大厂实习
独角仙梦境:这是真👻了
找实习记录
点赞 评论 收藏
分享
评论
1
1
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务