gpt4 book ai didi

reactjs - 如何重用 Redux Toolkit createSlice 函数中的 reducer 逻辑?

转载 作者:行者123 更新时间:2023-12-03 14:06:40 24 4
gpt4 key购买 nike

我是 React 的新手,我正在学习使用 React 来构建 Web 应用程序。我发现 Redux Toolkit 很有用并使用它的 createSlice()函数来实现基本功能。但是,我遇到了与“最佳实践”相关的问题,我不确定我是否正确构建了应用程序的架构。
假设我有一个 user对象存储在 Redux 中。我创建了一个异步 thunk 函数来获取相关信息:

export const getUserInfo = createAsyncThunk('user/get', async (userId, thunkApi) => {
// fetching information using api
}
相应地,我处理了 pending/fulfilled/rejected回调如下:
const userSlice = createSlice({
name: 'user',
initialState,
reducers: {
setShowProgress(state, action: PayloadAction<boolean>) {
state.showProgress = action.payload;
},
clearError(state) {
state.error = null;
state.errorMessage = null;
}
},
extraReducers: builder => {
builder.addCase(getUserInfo.pending, (state, action) => {
// My question is here >_<
}
builder.addCase(getUserInfo.fulfilled, (state, action) => {
// handle data assignments
})
builder.addCase(getUserInfo.rejected, (state, action) => {
// handle error messages
})
}
})
考虑到修改显示状态标志在其他功能 api 实现中很常见,我将两个函数( setShowProgress()clearError() )包装在 reducers 中.我的问题来了:如何引用 getUserInfo.pending 中的两个函数功能?
虽然我可以分配 showProgresserror getUserInfo.pending 中的状态变量而不是尝试调用reducer函数,当我将来实现其他获取操作时肯定会引入重复的代码。如果它不是推荐的模式,那么这种场景的最佳实践是什么?

最佳答案

如果您的目标只是设置一个 loading bool 值或 error属性基于 pending/fulfilled/rejected ,您可以使用 addMatcher这是在 1.4 版中引入的。
这是一个非常基本的示例,它使用通用助手在多个切片中简化此操作。

// First, we'll just create some helpers in the event you do this in other slices. I'd export these from a util.

const hasPrefix = (action: AnyAction, prefix: string) =>
action.type.startsWith(prefix);
const isPending = (action: AnyAction) => action.type.endsWith("/pending");
const isFulfilled = (action: AnyAction) => action.type.endsWith("/fulfilled");
const isRejected = (action: AnyAction) => action.type.endsWith("/rejected");

const isPendingAction = (prefix: string) => (
action: AnyAction
): action is AnyAction => { // Note: this cast to AnyAction could also be `any` or whatever fits your case best
return hasPrefix(action, prefix) && isPending(action);
};

const isRejectedAction = (prefix: string) => (
action: AnyAction
): action is AnyAction => { // Note: this cast to AnyAction could also be `any` or whatever fits your case best - like if you had standardized errors and used `rejectWithValue`
return hasPrefix(action, prefix) && isRejected(action);
};

const isFulfilledAction = (prefix: string) => (
action: AnyAction
): action is AnyAction => {
return hasPrefix(action, prefix) && isFulfilled(action);
};

const userSlice = createSlice({
name: 'user',
initialState,
reducers: {},
extraReducers: builder => {
builder.addCase(getUserInfo.fulfilled, (state, action) => {
// handle data assignments
})
// use scoped matchers to handle generic loading / error setting behavior for async thunks this slice cares about
.addMatcher(isPendingAction("user/"), state => {
state.loading = true;
state.error = '';
})
.addMatcher(isRejectedAction("user/"), (state, action) => {
state.loading = false;
state.error = action.error; // or you could use `rejectWithValue` and pull it from the payload.
})
.addMatcher(isFulfilledAction("user/"), state => {
state.loading = false;
state.error = '';
});
}
})

关于reactjs - 如何重用 Redux Toolkit createSlice 函数中的 reducer 逻辑?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62977443/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com