跳至主要內容

Redux Toolkit 快速入門

您將學到什麼
  • 如何設定和使用 Redux Toolkit 搭配 React-Redux
先備條件

簡介

歡迎使用 Redux Toolkit 快速入門教學!本教學課程將簡要介紹 Redux Toolkit,並教您如何開始正確使用它

如何閱讀本教學課程

本頁面將重點介紹如何使用 Redux Toolkit 設定 Redux 應用程式,以及您將使用的主要 API。如需了解 Redux 是什麼、其運作方式,以及如何使用 Redux Toolkit 的完整範例,請參閱「教學課程總覽」頁面中連結的教學課程

在本教學課程中,我們假設您將 Redux Toolkit 與 React 搭配使用,但您也可以將它與其他 UI 層搭配使用。這些範例基於 典型的 Create-React-App 資料夾結構,其中所有應用程式程式碼都位於 src 中,但這些模式可以調整為您使用的任何專案或資料夾設定。

適用於 Create-React-App 的 Redux+JS 範本附帶已設定好的相同專案設定。

使用摘要

安裝 Redux Toolkit 和 React-Redux

將 Redux Toolkit 和 React-Redux 套件新增到您的專案

npm install @reduxjs/toolkit react-redux

建立 Redux Store

建立一個名為 src/app/store.js 的檔案。從 Redux Toolkit 匯入 configureStore API。我們將從建立一個空的 Redux store 開始,並將其匯出

app/store.js
import { configureStore } from '@reduxjs/toolkit'

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

// Infer the `RootState` and `AppDispatch` types from the store itself
export type RootState = ReturnType<typeof store.getState>
// Inferred type: {posts: PostsState, comments: CommentsState, users: UsersState}
export type AppDispatch = typeof store.dispatch

這會建立一個 Redux store,並自動設定 Redux DevTools 擴充功能,以便您在開發時檢查 store。

提供 Redux Store 給 React

建立 store 之後,我們可以透過在 src/index.js 中的應用程式周圍放置 React-Redux <Provider>,讓 React 元件可以使用它。匯入我們剛剛建立的 Redux store,在 <App> 周圍放置一個 <Provider>,並將 store 傳遞為 prop

index.js
import React from 'react'
import ReactDOM from 'react-dom'
import './index.css'
import App from './App'
import { store } from './app/store'
import { Provider } from 'react-redux'

ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
)

建立 Redux 狀態區段

新增一個名為 src/features/counter/counterSlice.js 的檔案。在該檔案中,從 Redux Toolkit 匯入 createSlice API。

建立區段需要一個字串名稱來識別區段、一個初始狀態值,以及一個或多個 reducer 函式來定義如何更新狀態。建立區段後,我們可以匯出產生的 Redux 動作建立器和整個區段的 reducer 函式。

Redux 要求我們透過複製資料並更新副本,以不可變的方式撰寫所有狀態更新。然而,Redux Toolkit 的 createSlicecreateReducer API 在內部使用 Immer,讓我們能夠撰寫「變異」更新邏輯,並轉換成正確的不可變更新

features/counter/counterSlice.js
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) => {
// Redux Toolkit allows us to write "mutating" logic in reducers. It
// doesn't actually mutate the state because it uses the Immer library,
// which detects changes to a "draft state" and produces a brand new
// immutable state based off those changes
state.value += 1
},
decrement: (state) => {
state.value -= 1
},
incrementByAmount: (state, action: PayloadAction<number>) => {
state.value += action.payload
},
},
})

// Action creators are generated for each case reducer function
export const { increment, decrement, incrementByAmount } = counterSlice.actions

export default counterSlice.reducer

將區段 Reducer 加入 Store

接下來,我們需要從 counter 區段匯入 reducer 函式,並將其加入我們的 store。透過在 reducer 參數內定義一個欄位,我們告知 store 使用此區段 reducer 函式來處理該狀態的所有更新。

app/store.js
import { configureStore } from '@reduxjs/toolkit'
import counterReducer from '../features/counter/counterSlice'

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

// Infer the `RootState` and `AppDispatch` types from the store itself
export type RootState = ReturnType<typeof store.getState>
// Inferred type: {posts: PostsState, comments: CommentsState, users: UsersState}
export type AppDispatch = typeof store.dispatch

在 React 元件中使用 Redux 狀態和動作

現在,我們可以使用 React-Redux 勾子讓 React 元件與 Redux store 互動。我們可以使用 useSelector 從 store 讀取資料,並使用 useDispatch 派送動作。建立一個 src/features/counter/Counter.js 檔案,其中包含一個 <Counter> 元件,然後將該元件匯入 App.js 並在 <App> 內部渲染它。

features/counter/Counter.js
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>
)
}

現在,任何時候你按一下「遞增」和「遞減」按鈕

  • 對應的 Redux 動作將派送至 store
  • counter 區段 reducer 將看到動作並更新其狀態
  • <Counter> 元件將看到 store 中的新狀態值,並使用新資料重新渲染自身

你學到了什麼

這是如何設定和使用 Redux Toolkit 與 React 的簡要概述。回顧一下細節

摘要
  • 使用 configureStore 建立 Redux store
    • configureStore 接受一個 reducer 函式作為命名參數
    • configureStore 會自動設定儲存庫,並使用良好的預設設定
  • 將 Redux 儲存庫提供給 React 應用程式元件
    • <App /> 周圍放置一個 React-Redux <Provider> 元件
    • 傳遞 Redux 儲存庫作為 <Provider store={store}>
  • 使用 createSlice 建立一個 Redux 「區塊」reducer
    • 使用字串名稱、初始狀態和命名 reducer 函式呼叫 createSlice
    • reducer 函式可以使用 Immer「變異」狀態
    • 匯出產生的區塊 reducer 和動作建立器
  • 在 React 元件中使用 React-Redux useSelector/useDispatch 勾子
    • 使用 useSelector 勾子從儲存庫中讀取資料
    • 使用 useDispatch 勾子取得 dispatch 函式,並視需要發送動作

完整的計數器應用程式範例

這裡顯示的計數器範例應用程式也是

以下是完整的計數器應用程式,作為執行的 CodeSandbox

接下來是什麼?

我們建議瀏覽 Redux 核心文件中的「Redux Essentials」和「Redux Fundamentals」教學課程,這將讓你完全了解 Redux 的運作方式、Redux Toolkit 的功能以及如何正確使用它。