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。
全部评论

相关推荐

牛客928043833号:在他心里你已经是他的员工了
点赞 评论 收藏
分享
04-11 23:51
门头沟学院 Java
坚定的芭乐反对画饼_许愿Offer版:人人都能过要面试干嘛,发个美团问卷填一下,明天来上班不就好了
点赞 评论 收藏
分享
评论
1
1
分享

创作者周榜

更多
牛客网
牛客企业服务