我用的是redux toolkit。
我有不同的切片,它们有自己的状态。
我有一个切片角色
import { createSlice } from '@reduxjs/toolkit';
import { getAllRoles } from './roleActions';
const initialState = {
roles: [],
loading: false,
isSuccess: false,
message: '',
};
const authReducer = createSlice({
name: 'roles',
initialState,
reducers: {},
extraReducers: (builder) => {
builder
.addCase(getAllRoles.pending, (state) => {
state.isSuccess = false;
state.message = '';
state.loading = true;
})
.addCase(getAllRoles.fulfilled, (state, { payload }) => {
state.roles = payload.data;
state.message = payload.message;
state.isSuccess = true;
state.loading = false;
})
.addCase(getAllRoles.rejected, (state, { payload }) => {
state.isSuccess = false;
state.message = payload;
state.loading = false;
});
},
});
export default authReducer.reducer;
字符串
下面是getAllRoles操作
import { createAsyncThunk } from '@reduxjs/toolkit';
import API from '../../api';
import { formatError } from '@utils/index';
export const getAllRoles = createAsyncThunk('role/getAllRoles', async (_, { rejectWithValue }) => {
try {
const { data } = await API.get('/roles');
return data;
} catch (error) {
return rejectWithValue(formatError(error));
}
});
型
我正在获取所有角色:
useEffect(() => {
dispatch(getAllRoles());
}, [dispatch]);
型
另一片:
import { createSlice } from '@reduxjs/toolkit';
import { deleteJob, getJobs, updateJob, createJob } from './jobActions';
const initialValues = {
data: {
jobs: [],
totalCount: 0,
},
loading: false,
isSuccess: false,
message: '',
};
const jobsReducer = createSlice({
name: 'jobs',
initialState: initialValues,
reducers: {},
extraReducers: (builder) => {
// Get Jobs
builder
.addCase(getJobs.fulfilled, (state, { payload }) => {
return {
...state,
data: payload.data,
message: payload.message,
isSuccess: true,
loading: false,
};
})
.addCase(deleteJob.fulfilled, (state, { payload }) => {
const updatedJobs = [...state.data.jobs.filter((job) => job._id !== payload)];
return {
...state,
data: {
totalCount: state.data.totalCount - 1,
jobs: updatedJobs,
},
message: 'Job deleted successfully',
isSuccess: true,
loading: false,
};
})
.addCase(updateJob.fulfilled, (state, { payload }) => {
const updatedJobs = [...state.data.jobs.filter((job) => job._id !== payload.data._id), payload.data];
return {
...state,
data: {
totalCount: state.data.totalCount,
jobs: updatedJobs,
},
message: payload.message,
isSuccess: true,
loading: false,
};
})
.addCase(createJob.fulfilled, (state, { payload }) => {
return {
...state,
data: {
totalCount: state.data.totalCount + 1,
jobs: [payload.data, ...state.data.jobs],
},
message: payload.message,
isSuccess: true,
loading: false,
};
})
.addMatcher(
(action) => action.type.endsWith('/pending'),
(state) => ({
...state,
isSuccess: false,
message: '',
loading: true,
}),
)
.addMatcher(
(action) => action.type.endsWith('/rejected'),
(state, { payload }) => ({
...state,
isSuccess: false,
message: payload,
loading: false,
}),
);
},
});
export default jobsReducer.reducer;
型
再来一个slice:
import { createUser, deleteUser, getUsers, updateUser } from './userActions';
const initialState = {
users: [],
loading: false,
isSuccess: false,
message: '',
};
const usersReducer = createSlice({
name: 'users',
initialState,
reducers: {},
extraReducers: (builder) => {
// Get Users
builder.addCase(getUsers.fulfilled, (state, { payload }) => {
state.loading = false;
state.message = payload.message;
state.users = payload.data;
state.isSuccess = true;
});
// Delete Users
builder.addCase(deleteUser.fulfilled, (state, { payload }) => {
state.loading = false;
state.message = payload.message;
state.users = [...state.users.filter((user) => user._id !== payload)];
state.isSuccess = true;
});
// Update User
builder.addCase(updateUser.fulfilled, (state, { payload }) => {
state.loading = false;
state.message = payload.message;
state.users.splice(
state.users.findIndex((user) => user.email === payload.data.email),
1,
payload.data,
);
state.isSuccess = true;
state.message = payload.message;
});
// Create User
builder.addCase(createUser.fulfilled, (state, { payload }) => {
state.loading = false;
state.message = payload.message;
state.users.unshift(payload.data);
state.isSuccess = true;
});
// Pending State
builder.addMatcher(
(action) => action.type.endsWith('/pending'),
(state) => {
state.isSuccess = false;
state.message = '';
state.loading = true;
},
);
// Rejected State
builder.addMatcher(
(action) => action.type.endsWith('/rejected'),
(state, { payload }) => {
state.isSuccess = false;
state.message = payload;
state.loading = false;
},
);
},
});
export default usersReducer.reducer;
型
现在的问题是,当getAllRoles触发时,它应该将其加载状态更改为true,这样它就正确了,
但它也会将用户和作业的加载状态更改为true,仅将加载状态更改为true,而不会重新设置为false。
就像我有一些其他的切片一样,它们也是这样的,
当我调度getJobs的操作时,
现在它也有不同的行为,比如它将用户的加载状态更改为true,而不是角色或任何其他角色。
以下是redux devtools的截图:
x1c 0d1x的数据
我已经选择了roles/getAllRoles/pending action,并检查了状态差异,它正在改变其他切片的加载状态,这是不应该的。
以下是我的商店配置:
import storage from 'redux-persist/lib/storage';
import { combineReducers } from 'redux';
import { persistReducer } from 'redux-persist';
import thunk from 'redux-thunk';
import { authReducer, usersReducer, rolesReducer, jobsReducer, surveysReducer, pageInfoReducer } from './features';
const reducers = combineReducers({
auth: authReducer,
users: usersReducer,
roles: rolesReducer,
jobs: jobsReducer,
survey: surveysReducer,
pageInfo: pageInfoReducer,
});
const store = configureStore({
reducer: reducers,
devTools: process.env.NODE_ENV !== 'production',
middleware: [thunk],
});
export default store;
型
尝试删除addMatcher,为动作和切片使用唯一的名称,尝试单独使用builder.addCase而不是改变方式。没有任何效果。
1条答案
按热度按时间mbskvtky1#
问题
作业和用户状态切片都定义了reducer cases,用于处理 * 任何**挂起或拒绝的操作。
个字符
当
'role/getAllRoles/pending'
被分派到store时,这些其他reducer case将使用当前代码正确更新并设置其本地loading
状态(* 以及它们case中的状态更新 *)。如果异步getAllRoles
操作成功完成,则这些其他状态切片中没有清除其加载状态的情况。解决方案
回想一下,Redux store的reducer树中的所有reducer都会传递每个分派到store的action,并且只有具有特定action的case的reducer才会响应。
我怀疑您只对作业切片中
deleteJob
、getJobs
、updateJob
和createJob
操作的挂起/拒绝状态感兴趣,而对createUser
、deleteUser
、getUsers
、对于用户切片,我建议使用isPending
、isFulfilled
和isRejected
匹配实用程序。范例:
的字符串