React / Redux 警报最佳实践
React / Redux alerting best practices
我是 redux 的新手,我正在使用 redux 重建一个相当复杂的 reactjs 应用程序。
我认为为通知构建一个“功能”是有意义的,该功能将具有类似
的状态片段
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
import { RootState } from '../../app/store';
export interface NotificationState {
show: boolean,
status: 'info' | 'warn' | 'error' | 'success',
title: string,
message: string,
position: 'dash' | 'popover',
}
const initialState: NotificationState = {
show: false,
status: 'info',
title: '',
message: '',
position: 'popover',
};
export const notificationSlice = createSlice({
name: 'notification',
initialState,
reducers: {
show: (state, action: PayloadAction<NotificationState>) => {
state = action.payload;
},
hide: (state) => {
state.show = false;
},
toggle: (state) => {
state.show = !state.show;
},
},
});
const { actions, reducer } = notificationSlice;
export const { show, hide, toggle } = actions;
export const selectNotification = (state: RootState) => state.notification;
export default reducer;
这将控制通知的显示方式、位置、使用的警告颜色等。
但是,既然我开始着手实施,我发现我想根据其他功能的状态显示通知。例如,在我的 blog-posts
功能中,我通过 thunk
从服务器获取数据,我想根据 thunk 的状态设置通知:
extraReducers: (builder) => {
builder
.addCase(fetchBlogPosts.fulfilled, (state, action) => {
state.status = 'idle';
state.entities = action.payload;
})
// hopefully this will apply to any failed / pending request
.addMatcher(isRejectedAction, (state, action) => {
state.error = action.error;
// store.dispatch(show({
// show: true,
// status: 'error',
// title: 'Request Failed',
// message: action.error.message,
// position: 'popover',
// autoHide: false,
// confirm: false,
// }));
})
.addMatcher(isPendingAction, (state, action) => {
state.status = 'loading';
})
}
明显的问题是您不应该从 reducer 中调度 action。这通常只是一个坏主意,还是有办法从 thunk 响应中设置 notification
状态?有没有“最佳实践”的方法来处理这个问题?
在这种特殊情况下,我认为您需要翻转实现方法。
您可以让通知切片添加一个 extraReducers
案例来侦听任何“被拒绝”的操作,并根据该操作显示通知。多个 reducer 处理一个动作是我们特别鼓励的一种模式:
我是 redux 的新手,我正在使用 redux 重建一个相当复杂的 reactjs 应用程序。
我认为为通知构建一个“功能”是有意义的,该功能将具有类似
的状态片段import { createSlice, PayloadAction } from '@reduxjs/toolkit';
import { RootState } from '../../app/store';
export interface NotificationState {
show: boolean,
status: 'info' | 'warn' | 'error' | 'success',
title: string,
message: string,
position: 'dash' | 'popover',
}
const initialState: NotificationState = {
show: false,
status: 'info',
title: '',
message: '',
position: 'popover',
};
export const notificationSlice = createSlice({
name: 'notification',
initialState,
reducers: {
show: (state, action: PayloadAction<NotificationState>) => {
state = action.payload;
},
hide: (state) => {
state.show = false;
},
toggle: (state) => {
state.show = !state.show;
},
},
});
const { actions, reducer } = notificationSlice;
export const { show, hide, toggle } = actions;
export const selectNotification = (state: RootState) => state.notification;
export default reducer;
这将控制通知的显示方式、位置、使用的警告颜色等。
但是,既然我开始着手实施,我发现我想根据其他功能的状态显示通知。例如,在我的 blog-posts
功能中,我通过 thunk
从服务器获取数据,我想根据 thunk 的状态设置通知:
extraReducers: (builder) => {
builder
.addCase(fetchBlogPosts.fulfilled, (state, action) => {
state.status = 'idle';
state.entities = action.payload;
})
// hopefully this will apply to any failed / pending request
.addMatcher(isRejectedAction, (state, action) => {
state.error = action.error;
// store.dispatch(show({
// show: true,
// status: 'error',
// title: 'Request Failed',
// message: action.error.message,
// position: 'popover',
// autoHide: false,
// confirm: false,
// }));
})
.addMatcher(isPendingAction, (state, action) => {
state.status = 'loading';
})
}
明显的问题是您不应该从 reducer 中调度 action。这通常只是一个坏主意,还是有办法从 thunk 响应中设置 notification
状态?有没有“最佳实践”的方法来处理这个问题?
在这种特殊情况下,我认为您需要翻转实现方法。
您可以让通知切片添加一个 extraReducers
案例来侦听任何“被拒绝”的操作,并根据该操作显示通知。多个 reducer 处理一个动作是我们特别鼓励的一种模式: