减少样板 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;
});
}
})
我目前在我的 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;
});
}
})