Skip to content

Built-in RTK type to handle splitting reducers #3

Description

@psychedelicious

I have a big slice with many reducers and wanted to split it up. Looking at the type signature for createSlice, we can create an object of typed reducers like this:

import type { ActionReducerMapBuilder, PayloadAction, SliceCaseReducers } from '@reduxjs/toolkit';
import { createSlice } from '@reduxjs/toolkit';

type MySlice = {
  flavour: 'vanilla' | 'chocolate' | 'strawberry';
  sprinkles: boolean;
  customers: { id: string; name: string }[];
};
const initialStateMySlice: MySlice = { flavour: 'vanilla', sprinkles: false, customers: [] };

const reducersInAnotherFile = {
  sprinklesToggled: (state) => {
    state.sprinkles = !state.sprinkles;
  },
  customerAdded: {
    reducer: (state, action: PayloadAction<{ id: string; name: string }>) => {
      state.customers.push(action.payload);
    },
    prepare: (name: string) => ({ payload: { name, id: crypto.randomUUID() } }),
  },
} satisfies SliceCaseReducers<MySlice>;

const extraReducersInAnotherFile = (builder: ActionReducerMapBuilder<MySlice>) => {
  builder.addCase(otherSlice.actions.fooChanged, (state, action) => {
    if (action.payload === 'bar') {
      state.flavour = 'vanilla';
    }
  });
};

export const mySlice = createSlice({
  name: 'mySlice',
  initialState: initialStateMySlice,
  reducers: {
    ...reducersInAnotherFile,
    flavourChanged: (state, action: PayloadAction<MySlice['flavour']>) => {
      state.flavour = action.payload;
    },
  },
  extraReducers: extraReducersInAnotherFile,
});

type OtherSlice = {
  something: string;
};

const initialStateOtherSlice: OtherSlice = { something: 'foo' };

export const otherSlice = createSlice({
  name: 'otherSlice',
  initialState: initialStateOtherSlice,
  reducers: {
    fooChanged: (state, action: PayloadAction<string>) => {
      state.something = action.payload;
    },
  },
});

I suppose this wasn't an option back when this library was created - or maybe I'm missing something! Also, I understand this library does more than just this - but I wonder if RTK now has types for the other utilities here.

Anyways, in case anybody wants to split up their reducers, this is working fine for me without an extra dependencies.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions