Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Built-in RTK type to handle splitting reducers #3

Open
psychedelicious opened this issue Jun 15, 2024 · 0 comments
Open

Built-in RTK type to handle splitting reducers #3

psychedelicious opened this issue Jun 15, 2024 · 0 comments

Comments

@psychedelicious
Copy link

psychedelicious commented Jun 15, 2024

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant