Skip to main content

Slice

Content

Slices as well as AsyncThunks are stored together for better readability and remove need to have additional imports.

Creation

Slices are created the same way as described in documentation.

E.g. systemSlice.ts:

export const {reducer: SystemReducer} = createSlice({
name: "system",
initialState: SystemInitialState,
reducers: {
setOnboarding: onboardingHandler,
},
extraReducers: (builder) => {
builder.addCase(REHYDRATE, rehydrate);
},
});

In extraReducers don't forget to add the REHYDRATE case to set properly store after rehydration:

function rehydrate(state: SystemState, rehydrateParams: RehydrateAppAction) {
return newState(rehydrateParams.payload?.system || state, {isOnboardingVisited: rehydrateParams.payload != null});
}

Adding reducer to RootReducer

To see and use our reducer, first it has to be added into RootReducer, which is constructed using combineReducers and can be found in src/core/store/rootReducer.ts.

E.g. of adding SystemReducer into RootReducer:

export const rootReducer = combineReducers({
system: SystemReducer,
});

Parameter should be the same as name which was used in createSlice

Case handlers

Case handlers as you could see in example of the rehydrate case should be handled as a separate function for better readability.

Return newState

Even though Immer is used under the hood of the toolkit, it's still better to return newState rather than change properties directly without returning anything.

function rehydrate(state: SystemState, rehydrateParams: RehydrateAppAction) {
return newState(rehydrateParams.payload?.system || state, {isOnboardingVisited: rehydrateParams.payload != null});
}