What You'll Learn
Welcome to the Redux Toolkit Quick Start tutorial! This tutorial will briefly introduce you to Redux Toolkit and teach you how to start using it correctly.
How to Read This TutorialThis page will focus on just how to set up a Redux application with Redux Toolkit and the main APIs you'll use. For explanations of what Redux is, how it works, and full examples of how to use Redux Toolkit, see the tutorials linked in the "Tutorials Overview" page.
For this tutorial, we assume that you're using Redux Toolkit with React, but you can also use it with other UI layers as well. The examples are based on a typical Create-React-App folder structure where all the application code is in a src
, but the patterns can be adapted to whatever project or folder setup you're using.
The Redux+JS template for Create-React-App comes with this same project setup already configured.
Usage Summary Install Redux Toolkit and React-ReduxAdd the Redux Toolkit and React-Redux packages to your project:
npm install @reduxjs/toolkit react-redux
Create a Redux Store
Create a file named src/app/store.js
. Import the configureStore
API from Redux Toolkit. We'll start by creating an empty Redux store, and exporting it:
app/store.ts
import { configureStore } from '@reduxjs/toolkit'
export const store = configureStore({
reducer: {},
})
export type RootState = ReturnType<typeof store.getState>
export type AppDispatch = typeof store.dispatch
app/store.js
import { configureStore } from '@reduxjs/toolkit'
export const store = configureStore({
reducer: {},
})
This creates a Redux store, and also automatically configure the Redux DevTools extension so that you can inspect the store while developing.
Provide the Redux Store to ReactOnce the store is created, we can make it available to our React components by putting a React-Redux <Provider>
around our application in src/index.js
. Import the Redux store we just created, put a <Provider>
around your <App>
, and pass the store as a prop:
index.ts
import React from 'react'
import { createRoot } from 'react-dom/client'
import './index.css'
import App from './App'
import { store } from './app/store'
import { Provider } from 'react-redux'
const container = document.getElementById('root')
if (container) {
const root = createRoot(container)
root.render(
<Provider store={store}>
<App />
</Provider>,
)
} else {
throw new Error(
"Root element with ID 'root' was not found in the document. Ensure there is a corresponding HTML element with the ID 'root' in your HTML file.",
)
}
index.js
import React from 'react'
import { createRoot } from 'react-dom/client'
import './index.css'
import App from './App'
import { store } from './app/store'
import { Provider } from 'react-redux'
const container = document.getElementById('root')
if (container) {
const root = createRoot(container)
root.render(
<Provider store={store}>
<App />
</Provider>,
)
} else {
throw new Error(
"Root element with ID 'root' was not found in the document. Ensure there is a corresponding HTML element with the ID 'root' in your HTML file.",
)
}
Create a Redux State Slice
Add a new file named src/features/counter/counterSlice.js
. In that file, import the createSlice
API from Redux Toolkit.
Creating a slice requires a string name to identify the slice, an initial state value, and one or more reducer functions to define how the state can be updated. Once a slice is created, we can export the generated Redux action creators and the reducer function for the whole slice.
Redux requires that we write all state updates immutably, by making copies of data and updating the copies. However, Redux Toolkit's createSlice
and createReducer
APIs use Immer inside to allow us to write "mutating" update logic that becomes correct immutable updates.
features/counter/counterSlice.ts
import { createSlice } from '@reduxjs/toolkit'
import type { PayloadAction } from '@reduxjs/toolkit'
export interface CounterState {
value: number
}
const initialState: CounterState = {
value: 0,
}
export const counterSlice = createSlice({
name: 'counter',
initialState,
reducers: {
increment: (state) => {
state.value += 1
},
decrement: (state) => {
state.value -= 1
},
incrementByAmount: (state, action: PayloadAction<number>) => {
state.value += action.payload
},
},
})
export const { increment, decrement, incrementByAmount } = counterSlice.actions
export default counterSlice.reducer
features/counter/counterSlice.js
import { createSlice } from '@reduxjs/toolkit'
const initialState = {
value: 0,
}
export const counterSlice = createSlice({
name: 'counter',
initialState,
reducers: {
increment: (state) => {
state.value += 1
},
decrement: (state) => {
state.value -= 1
},
incrementByAmount: (state, action) => {
state.value += action.payload
},
},
})
export const { increment, decrement, incrementByAmount } = counterSlice.actions
export default counterSlice.reducer
Add Slice Reducers to the Store
Next, we need to import the reducer function from the counter slice and add it to our store. By defining a field inside the reducer
parameter, we tell the store to use this slice reducer function to handle all updates to that state.
app/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
app/store.js
import { configureStore } from '@reduxjs/toolkit'
import counterReducer from '../features/counter/counterSlice'
export const store = configureStore({
reducer: {
counter: counterReducer,
},
})
Use Redux State and Actions in React Components
Now we can use the React-Redux hooks to let React components interact with the Redux store. We can read data from the store with useSelector
, and dispatch actions using useDispatch
. Create a src/features/counter/Counter.js
file with a <Counter>
component inside, then import that component into App.js
and render it inside of <App>
.
features/counter/Counter.ts
import React from 'react'
import type { RootState } from '../../app/store'
import { useSelector, useDispatch } from 'react-redux'
import { decrement, increment } from './counterSlice'
export function Counter() {
const count = useSelector((state: RootState) => state.counter.value)
const dispatch = useDispatch()
return (
<div>
<div>
<button
aria-label="Increment value"
onClick={() => dispatch(increment())}
>
Increment
</button>
<span>{count}</span>
<button
aria-label="Decrement value"
onClick={() => dispatch(decrement())}
>
Decrement
</button>
</div>
</div>
)
}
features/counter/Counter.js
import React from 'react'
import { useSelector, useDispatch } from 'react-redux'
import { decrement, increment } from './counterSlice'
export function Counter() {
const count = useSelector((state) => state.counter.value)
const dispatch = useDispatch()
return (
<div>
<div>
<button
aria-label="Increment value"
onClick={() => dispatch(increment())}
>
Increment
</button>
<span>{count}</span>
<button
aria-label="Decrement value"
onClick={() => dispatch(decrement())}
>
Decrement
</button>
</div>
</div>
)
}
Now, any time you click the "Increment" and "Decrement" buttons:
<Counter>
component will see the new state value from the store and re-render itself with the new dataThat was a brief overview of how to set up and use Redux Toolkit with React. Recapping the details:
Summary
configureStore
configureStore
accepts a reducer
function as a named argumentconfigureStore
automatically sets up the store with good default settings<Provider>
component around your <App />
<Provider store={store}>
createSlice
createSlice
with a string name, an initial state, and named reducer functionsuseSelector/useDispatch
hooks in React components
useSelector
hookdispatch
function with the useDispatch
hook, and dispatch actions as neededThe counter example app shown here is also the
Here's the complete counter application as a running CodeSandbox:
What's Next?We recommend going through the "Redux Essentials" and "Redux Fundamentals" tutorials in the Redux core docs, which will give you a complete understanding of how Redux works, what Redux Toolkit does, and how to use it correctly.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4