如何从 redux 工具包异步 thunk 的挂起状态修改另一个切片的状态
how to modify the state of another slice from pending state of redux toolkit async thunk
我正在构建一个简单的应用程序。我正在使用 redux 工具包进行状态管理
它必须查询数据库以检查用户是否已通过身份验证。
如果是,它会为用户设置姓名、电子邮件等
在检查数据库时,我想在前端加载一个微调器,微调器占据整个屏幕,并会在数据库查询时随时显示。出于这个原因,我想要一个单独的应用程序状态,它有两个值,即加载和错误
appSlice
const initialState = {loading : false,error:false,error_msg:null}
export const appSlice = createSlice({
name : 'app',
initialState : {value : initialState},
reducers : {
toggle : (state,action)=>{
state.value.loading = action.payload
}
},
});
userSlice
const initialState = { name: "", email: "", role: "", isAuthenticated: false };
export const authenticateUser = createAsyncThunk(
"user/authenticate",
async () => {
let res = await axiosInstance.get("/user/authenticate");
return res.data;
}
);
export const userSlice = createSlice({
name: "user",
initialState: { value: initialState },
reducers: {},
extraReducers: (builder) => {
builder.addCase(authenticateUser.pending, (state, action) => {
//change loading to true for app slice something like (state.app.loading = true)
});
builder.addCase(authenticateUser.fulfilled, (state, action) => {
state.value = action.payload
});
builder.addCase(authenticateUser.rejected, (state, action) => {
//change error to true for app slice something like (state.app.error = true)
//change error_msg to action.payload for app slice
//something like (state.app.error_msg = action.payload)
});
},
});
您可以在不同的状态片中处理一个动作。您应该在 appSlice
的 userSlice
文件中引用 authenticateUser.pending
和 authenticateUser.rejected
动作创建者,并在 appSlice
的 extraReducers
中处理它们。
例如,如果 user/authenticate
操作因错误而失败。
import { configureStore, createAsyncThunk, createSlice } from '@reduxjs/toolkit';
export const authenticateUser = createAsyncThunk<any, any, { rejectValue: { error: string } }>(
'user/authenticate',
async (_, { rejectWithValue }) => {
// success
// return { name: 'teresa teng', email: 'teresa@gmail.com', role: 'admin', isAuthenticated: true };
// fail
return rejectWithValue({ error: 'network error' }) as unknown as { error: string };
},
);
export const userSlice = createSlice({
name: 'user',
initialState: { value: { name: '', email: '', role: '', isAuthenticated: false } },
reducers: {},
extraReducers: (builder) => {
builder.addCase(authenticateUser.fulfilled, (state, action) => {
state.value = action.payload;
});
},
});
export const appSlice = createSlice({
name: 'app',
initialState: { value: { loading: false, error: false, error_msg: '' } },
reducers: {
toggle: (state, action) => {
state.value.loading = action.payload;
},
},
extraReducers: (builder) => {
builder.addCase(authenticateUser.pending, (state, action) => {
state.value.loading = true;
});
builder.addCase(authenticateUser.rejected, (state, action) => {
state.value.error = true;
state.value.error_msg = action.payload?.error || 'unknown error';
});
},
});
const store = configureStore({
reducer: { app: appSlice.reducer, user: userSlice.reducer },
});
store.dispatch(authenticateUser({}));
store.subscribe(() => {
console.log(store.getState());
});
输出:
{
app: { value: { loading: true, error: true, error_msg: 'network error' } },
user: { value: { name: '', email: '', role: '', isAuthenticated: false } }
}
我正在构建一个简单的应用程序。我正在使用 redux 工具包进行状态管理
它必须查询数据库以检查用户是否已通过身份验证。
如果是,它会为用户设置姓名、电子邮件等
在检查数据库时,我想在前端加载一个微调器,微调器占据整个屏幕,并会在数据库查询时随时显示。出于这个原因,我想要一个单独的应用程序状态,它有两个值,即加载和错误
appSlice
const initialState = {loading : false,error:false,error_msg:null}
export const appSlice = createSlice({
name : 'app',
initialState : {value : initialState},
reducers : {
toggle : (state,action)=>{
state.value.loading = action.payload
}
},
});
userSlice
const initialState = { name: "", email: "", role: "", isAuthenticated: false };
export const authenticateUser = createAsyncThunk(
"user/authenticate",
async () => {
let res = await axiosInstance.get("/user/authenticate");
return res.data;
}
);
export const userSlice = createSlice({
name: "user",
initialState: { value: initialState },
reducers: {},
extraReducers: (builder) => {
builder.addCase(authenticateUser.pending, (state, action) => {
//change loading to true for app slice something like (state.app.loading = true)
});
builder.addCase(authenticateUser.fulfilled, (state, action) => {
state.value = action.payload
});
builder.addCase(authenticateUser.rejected, (state, action) => {
//change error to true for app slice something like (state.app.error = true)
//change error_msg to action.payload for app slice
//something like (state.app.error_msg = action.payload)
});
},
});
您可以在不同的状态片中处理一个动作。您应该在 appSlice
的 userSlice
文件中引用 authenticateUser.pending
和 authenticateUser.rejected
动作创建者,并在 appSlice
的 extraReducers
中处理它们。
例如,如果 user/authenticate
操作因错误而失败。
import { configureStore, createAsyncThunk, createSlice } from '@reduxjs/toolkit';
export const authenticateUser = createAsyncThunk<any, any, { rejectValue: { error: string } }>(
'user/authenticate',
async (_, { rejectWithValue }) => {
// success
// return { name: 'teresa teng', email: 'teresa@gmail.com', role: 'admin', isAuthenticated: true };
// fail
return rejectWithValue({ error: 'network error' }) as unknown as { error: string };
},
);
export const userSlice = createSlice({
name: 'user',
initialState: { value: { name: '', email: '', role: '', isAuthenticated: false } },
reducers: {},
extraReducers: (builder) => {
builder.addCase(authenticateUser.fulfilled, (state, action) => {
state.value = action.payload;
});
},
});
export const appSlice = createSlice({
name: 'app',
initialState: { value: { loading: false, error: false, error_msg: '' } },
reducers: {
toggle: (state, action) => {
state.value.loading = action.payload;
},
},
extraReducers: (builder) => {
builder.addCase(authenticateUser.pending, (state, action) => {
state.value.loading = true;
});
builder.addCase(authenticateUser.rejected, (state, action) => {
state.value.error = true;
state.value.error_msg = action.payload?.error || 'unknown error';
});
},
});
const store = configureStore({
reducer: { app: appSlice.reducer, user: userSlice.reducer },
});
store.dispatch(authenticateUser({}));
store.subscribe(() => {
console.log(store.getState());
});
输出:
{
app: { value: { loading: true, error: true, error_msg: 'network error' } },
user: { value: { name: '', email: '', role: '', isAuthenticated: false } }
}