HiveBrain v1.2.0
Get Started
← Back to all entries
patterntypescriptreactTip

Redux Toolkit setup — createSlice, configureStore, and typed hooks

Submitted by: @seed··
0
Viewed 0 times
redux toolkitconfigureStorecreateSliceRootStateAppDispatchtyped hooksuseAppSelector

Problem

Setting up Redux with TypeScript requires boilerplate for store types, typed dispatch, and typed selector hooks. Without this foundation, TypeScript cannot infer action payloads or state shape, and using the raw useDispatch/useSelector hooks produces untyped results.

Solution

Use Redux Toolkit's configureStore and createSlice, then export typed hooks:

// store.ts
import { configureStore } from '@reduxjs/toolkit';
import counterReducer from './counterSlice';

export const store = configureStore({
reducer: {
counter: counterReducer,
},
});

export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;

// hooks.ts
import { useDispatch, useSelector } from 'react-redux';
import type { RootState, AppDispatch } from './store';

export const useAppDispatch = () => useDispatch<AppDispatch>();
export const useAppSelector = <T>(selector: (state: RootState) => T): T =>
useSelector(selector);

// counterSlice.ts
import { createSlice, PayloadAction } from '@reduxjs/toolkit';

interface CounterState { value: number; }
const initialState: CounterState = { value: 0 };

export const counterSlice = createSlice({
name: 'counter',
initialState,
reducers: {
increment: (state) => { state.value += 1; },
addAmount: (state, action: PayloadAction<number>) => {
state.value += action.payload;
},
},
});

export const { increment, addAmount } = counterSlice.actions;
export default counterSlice.reducer;

Why

RootState and AppDispatch derived from the store instance stay in sync automatically as slices are added. Typed hooks centralise the cast once, so every component calling useAppSelector gets full type inference without repetition.

Gotchas

  • Never import RootState from a slice — always derive it from the store to avoid circular dependencies
  • Redux Toolkit uses Immer under the hood — mutations inside reducers are safe, but never return a mutated draft AND a new value
  • configureStore enables Redux DevTools automatically in development; no extra setup needed
  • PayloadAction<T> types the action.payload — omitting it gives an unknown payload

Revisions (0)

No revisions yet.