Redux Toolkit is the recommended way to write Redux logic in modern React and React Native applications. When TypeScript is used with Redux Toolkit, we can create strongly typed state, actions, reducers, selectors, and dispatch functions.
In this lesson, we will learn how to configure a Redux store, create slices, define state interfaces, use typed hooks, dispatch actions, read state, and connect Redux Toolkit with a React Native application.
configureStore() and createSlice().
Redux is a state management library that provides a centralized store for application state.
Instead of passing the same data through many components, different components can access shared state from the Redux store.
Redux Toolkit is a collection of tools that makes Redux easier to configure and use.
configureStore()createSlice()createAsyncThunk()Install Redux Toolkit and React Redux in a React Native project:
npm install @reduxjs/toolkit react-redux
These packages provide Redux functionality and React bindings.
interface CounterState {
value: number;
}
const initialState: CounterState = {
value: 0
};
The interface describes the structure of the Redux state.
import {
createSlice
} from "@reduxjs/toolkit";
const counterSlice =
createSlice({
name: "counter",
initialState,
reducers: {}
});
A slice contains a section of application state and the reducers that update that state.
const counterSlice =
createSlice({
name: "counter",
initialState,
reducers: {
increment: (
state
) => {
state.value += 1;
}
}
});
export const {
increment
} = counterSlice.actions;
Redux Toolkit automatically creates action creators for reducers defined inside the slice.
export default
counterSlice.reducer;
The generated reducer is added to the Redux store.
import {
configureStore
} from "@reduxjs/toolkit";
import counterReducer
from "./counterSlice";
export const store =
configureStore({
reducer: {
counter:
counterReducer
}
});
export type RootState =
ReturnType<typeof store.getState>;
RootState represents the complete state structure of the
Redux store.
export type AppDispatch =
typeof store.dispatch;
This type represents the dispatch function provided by the Redux store.
import {
Provider
} from "react-redux";
import {
store
} from "./store";
<Provider store={store}>
<App />
</Provider>
The Provider makes the Redux store available to components below it.
import {
useSelector
} from "react-redux";
const count =
useSelector(
(state: RootState) =>
state.counter.value
);
useSelector() reads data from the Redux store.
import {
useDispatch
} from "react-redux";
const dispatch =
useDispatch<AppDispatch>();
dispatch(increment());
The typed dispatch function can safely dispatch Redux actions.
import {
useDispatch,
useSelector
} from "react-redux";
export const useAppDispatch =
useDispatch.withTypes<AppDispatch>();
export const useAppSelector =
useSelector.withTypes<RootState>();
Typed hooks can make Redux usage cleaner across the application.
const count =
useAppSelector(
state =>
state.counter.value
);
TypeScript knows the structure of the Redux state through
RootState.
const dispatch =
useAppDispatch();
dispatch(increment());
The component dispatches the action generated by the counter slice.
reducers: {
incrementBy: (
state,
action: PayloadAction<number>
) => {
state.value += action.payload;
}
}
PayloadAction<number> tells TypeScript that the action
payload must be a number.
dispatch(
incrementBy(5)
);
The payload is passed to the generated action creator.
interface User {
id: number;
name: string;
email: string;
}
interface UserState {
user: User | null;
}
const initialState:
UserState = {
user: null
};
const userSlice =
createSlice({
name: "user",
initialState,
reducers: {
setUser: (
state,
action:
PayloadAction<User>
) => {
state.user =
action.payload;
},
clearUser: (
state
) => {
state.user = null;
}
}
});
function ProfileScreen():
React.JSX.Element {
const user =
useAppSelector(
state =>
state.user.user
);
return (
<View>
<Text>
{user?.name}
</Text>
</View>
);
}
A React Native screen can read Redux state using a typed selector.
any for Redux state.configureStore() to create the store.createSlice() for Redux logic.PayloadAction.Context API is useful for sharing relatively simple application-wide values such as themes or user information.
Redux Toolkit provides a structured state management system with actions, reducers, middleware, selectors, and a centralized store.
The choice depends on the application's requirements and complexity.
src/
app/
store.ts
hooks.ts
features/
counter/
counterSlice.ts
user/
userSlice.ts
screens/
HomeScreen.tsx
ProfileScreen.tsx
Organizing Redux code by features can make larger applications easier to maintain.
// counterSlice.ts
import {
createSlice,
PayloadAction
} from "@reduxjs/toolkit";
interface CounterState {
value: number;
}
const initialState:
CounterState = {
value: 0
};
const counterSlice =
createSlice({
name: "counter",
initialState,
reducers: {
increment: (
state
) => {
state.value += 1;
},
decrement: (
state
) => {
state.value -= 1;
},
incrementBy: (
state,
action:
PayloadAction<number>
) => {
state.value +=
action.payload;
}
}
});
export const {
increment,
decrement,
incrementBy
} = counterSlice.actions;
export default
counterSlice.reducer;
// store.ts
import {
configureStore
} from "@reduxjs/toolkit";
import counterReducer
from "../features/counter/counterSlice";
export const store =
configureStore({
reducer: {
counter:
counterReducer
}
});
export type RootState =
ReturnType<typeof store.getState>;
export type AppDispatch =
typeof store.dispatch;
import React from "react";
import {
View,
Text,
Button
} from "react-native";
import {
useAppDispatch,
useAppSelector
} from "../app/hooks";
import {
increment,
decrement
} from "../features/counter/counterSlice";
export default function CounterScreen():
React.JSX.Element {
const count =
useAppSelector(
state =>
state.counter.value
);
const dispatch =
useAppDispatch();
return (
<View>
<Text>
Count: {count}
</Text>
<Button
title="Increase"
onPress={() =>
dispatch(increment())
}
/>
<Button
title="Decrease"
onPress={() =>
dispatch(decrement())
}
/>
</View>
);
}
The screen reads typed Redux state and dispatches typed actions.
Redux Toolkit provides a structured way to manage shared application state in React Native. TypeScript adds type safety to the store, state objects, actions, reducers, selectors, and dispatch functions.
You should now understand Redux Toolkit installation, state interfaces, slices, reducers, actions, payloads, the Redux store, RootState, AppDispatch, typed hooks, React Native integration, and project organization.
configureStore() to create the store.createSlice() to create state logic.PayloadAction to type action payloads.RootState and AppDispatch types.Question: Which Redux Toolkit function is commonly used to create a slice of state with reducers and actions?