减少样板 Redux

Reducing Boilerplate Redux

我目前在我的 Redux-Thunk 应用程序中使用 Ducks Pattern。但是,我看到 Action Creators 中似乎有很多重复代码。我有更多的获取逻辑,它类似于下面的代码。我怎样才能使我的代码更清晰并摆脱重复的样板文件?此外,通过在 componentDidMount 内部调用,使用 Promise.all 或 运行 加载所有提取是否更好?

/* 
@ ACTION TYPES 
*/
const FETCH_BIRTHDAY_LOAD = "FETCH_BIRTHDAY_LOAD";
const FETCH_BIRTHDAY_SUCCESS = "FETCH_BIRTHDAY_SUCCESS";

const FETCH_ANNIVERSAY_LOAD = "FETCH_ANNIVERSAY_LOAD";
const FETCH_ANNIVERSAY_SUCCESS = "FETCH_ANNIVERSAY_SUCCESS"
const FETCH_FAILED = "FETCH_FAILED";
/* 
@ Action Creator
*/
export const fetchBirthday = () => {
    return function(dispatch) {
        dispatch({type : FETCH_BIRTHDAY_LOAD , payload : FETCH_BIRTHDAY_LOAD});
        return fetch(`${EMPLOYEE_URI}?stype=birthday`)
            .then(response => response.json().then(data => dispatch({ type:          FETCH_BIRTHDAY_SUCCESS, payload: data })))
            .catch(err => {
                dispatch({ type: FETCH_FAILED, payload: { name: FETCH_BIRTHDAY_LOAD, errorMessage: err.message } })
            })  
    }           
}
             


export const fetchAnniversary = () => {
    return function(dispatch) {
        dispatch({ type: FETCH_ANNIVERSAY_LOAD, payload: FETCH_BIRTHDAY_LOAD });
        
        return fetch(`${ENDPOINT.EMPLOYEE}`)
            .then(response => response.json().then(data => dispatch({ type: FETCH_ANNIVERSAY_SUCCESS, payload: data })))
            .catch(err => {
                dispatch({ type: FETCH_FAILED, payload: { name: FETCH_ANNIVERSAY_LOAD, errorMessage: err.message } })
            })  
    }
}

/*
@ Initial State
*/
const initialState = {
    birthAnniversaryData: [],
    anniversaryData: [],
    error : null
}


export default function home( state = initialState , action){

    const {type, payload } = action;

    switch(type) {
        case FETCH_BIRTHDAY_LOAD :
            return {...state, isLoading : true, error : null}

        case FETCH_ANNIVERSAY_LOAD :
            return { ...state, isLoading: true, error: null }
    case FETCH_BIRTHDAY_SUCCESS : 
        return { ...state, birthAnniversaryData: payload, }

    case FETCH_ANNIVERSAY_SUCCESS : 
        return {...state, workAnniversaryData : payload, }
        case FETCH_FAILED:
            return { error: payload }

        default : 
            return state;
    }
}

您应该改用 our official Redux Toolkit package,其中包括用于简化几个常见 Redux 用例的实用程序,包括存储设置、定义缩减器、不可变更新逻辑,甚至一次创建整个状态“切片”。它的 createSlice API 会自动为您生成动作创建器,无需手动编写它们。它还有一个 createAsyncThunk API 来处理基于承诺的调度操作。

您的代码可以简化为:

import {createSlice, createAsyncThunk} from "@reduxjs/toolkit";

const fetchBirthday = createAsyncThunk(
  'dates/fetchBirthday',
  async () => {
    return fetch(`${EMPLOYEE_URI}?stype=birthday`).then(res => res.json());
  }
);

const fetchBirthday = createAsyncThunk(
  'dates/fetchAnniversay',
  async () => {
    return fetch(`${ENDPOINT.EMPLOYEE}`).then(res => res.json());
  }
);

const initialState = {
    birthAnniversaryData: [],
    anniversaryData: [],
    error : null
}

const dateSlice = createSlice({
  name: "dates",
  initialState,
  reducers: {
    // add reducers that manipulate the data here. These will generate
    // corresponding action creators automatically.
    // Reducers use Immer, so you can "mutate" the state safely.
  },
  extraReducers: (builder) => {
    // Handle any actions that were not defined in the slice here
    
    builder.addCase(fetchBirthday.pending, (state, action) => {
      state.isLoading = true;
      state.error = null;
    })
    
    builder.addCase(fetchBirthday.pending, (state, action) => {
      state.isLoading = true;
      state.error = null;
    });
    
    builder.addCase(fetchBirthday.fulfilled, (state, action) => {
      state.birthAnniversaryData = action.payload;
    });
    
    builder.addCase(fetchAnniversary.fulfilled, (state, action) => {
      state.workAnniversaryData = action.payload;
    });
  }
})