快速入門Redux

更新 發佈閱讀 12 分鐘

前導

在 React 中,狀態管理是構建複雜應用的重要一環,其中 useContext 與 Redux 都提供了解決方案,但它們各有優缺點和適用場景。

  • useContext 更加簡單、直觀,適合較小或中等規模的應用。
  • Redux 則提供了更嚴謹的架構,適合大型應用或需要細緻控制狀態更新的場景。
  • 小型/中型應用: 如果應用不需要處理大量複雜狀態,且狀態更新頻率較低,使用 useContext(有時候與 useReducer 結合)可以減少開發複雜度。
  • 大型/複雜應用: 如果應用狀態較多且更新頻繁,或需要跨多個組件共享大量數據,Redux 提供的集中管理和調試能力能夠更好地應對複雜情況。

核心原則

  • 單一數據來源
    整個應用的狀態存儲在一個唯一的 store 中,這使得應用狀態集中、易於管理與調試。
  • 狀態只讀
    改變狀態的唯一途徑是發送(dispatch)一個 action。這些 action 是普通 JavaScript 物件,用於描述“發生了什麼事”。這樣的設計強制應用遵循單向數據流,使狀態變化更容易追蹤。
  • 使用純函數處理狀態變更
    Reducer 是純函數,它根據先前的狀態和收到的 action 計算並返回新的狀態。純函數不會改變傳入的狀態,而是返回一個全新的狀態物件,從而保持狀態的不變性。

2. 主要概念個別解析

  • Store
    Redux 的 store 是一個對象,包含了應用的所有狀態。唯一的 store 提供了一個全局的狀態樹,便於跨組件共享數據。
  • Action
    Action 是一個描述事件的 JavaScript 物件,必須包含一個 type 屬性(通常為字符串),這個屬性定義了該 action 的類型。Action 可以攜帶其他數據(payload),幫助 reducer 更新狀態。
  • Reducer
    Reducer 是一個純函數,負責根據當前狀態和 action 的類型來生成新的狀態。它不會修改原始狀態,而是返回一個新的狀態物件,這樣做能保持狀態的不可變性。
  • Dispatch
    當需要改變狀態時,應用會通過 dispatch 發送一個 action,store 收到 action 後會調用相應的 reducer 來更新狀態。
  • Subscribe
    應用可以訂閱 store 的狀態變化,當狀態發生改變時,訂閱者(通常是 UI 組件)會收到通知並更新其視圖。


Redux Toolkit 是什麼?

Redux Toolkit 是 Redux 官方推薦的工具集,旨在簡化 Redux 的使用,減少樣板程式碼,並提供更好的開發體驗。它包含了一些常用的 Redux 功能,並提供了一些工具來幫助你更快地建立 Redux store、定義 reducer 和 action。


Redux Toolkit 使用範例

這裡是一個使用 Redux Toolkit 建立的計數器小程式,具備 +1-1addBy(amount) 三種功能。

步驟概覽

  1. 建立 Redux Store:使用 @reduxjs/toolkit 建立 store,並撰寫 reducer 來處理計數邏輯。
  2. 建立 React 元件:使用 react-redux 連接 store 並透過按鈕操作數值。
  3. 組合與渲染應用

實際操作

  1. 首先,我們可以按照先前我們創建 React 環境一樣創建新的工作環境。
  2. 然號需要安裝必要的套件:
npm install @reduxjs/toolkit react-redux
  1. 建立 Redux Store,先在工作目錄的src資料夾下新增store資料夾,接著在裡面新增store.jsx
    store.jsx中使用 configureStore 來建立 Redux Toolkit store:
import { configureStore, createSlice } from '@reduxjs/toolkit';

// 建立 slice (類似 reducer)
const counterSlice = createSlice({
name: 'counter',
initialState: { value: 0 }, // 初始狀態
reducers: {
increment: (state) => {
state.value += 1;
},
decrement: (state) => {
state.value -= 1;
},
addBy: (state, action) => {
state.value += action.payload;
},
},
});

// 匯出 actions
export const { increment, decrement, addBy } = counterSlice.actions;

// 建立 store
const store = configureStore({
reducer: {
counter: counterSlice.reducer,
},
});

export default store;

createSlice 裡,name 主要是:

  • 用來區分 slice,這樣 Redux DevTools 會顯示它的名稱,方便除錯。
  • 與 action type 相關,RTK 會自動幫我們生成 action type,例如:這些 action type 就是 name + reducer function 名稱 的組合。
counter/increment
counter/decrement
counter/addBy
  • 程式碼中,name: 'counter' 並不是一定要叫 "counter",你可以改成 "myCounter" 或 其他名稱,但它影響的是 action type 的前綴。

createSlice裡,我們定義 initialState

initialState: { value: 0 }
  • 這代表這個 slice 一開始的狀態是 { value: 0 }。

在 reducer 裡,state 代表當前的 slice (目前counter)的狀態(例如 value: 5)

increment: (state) => {
state.value += 1;
}
  • 每次 increment 執行時,這個 state.value 就會 +1
  • 例如state.value += 1;value 變成 6

在 Redux Toolkit 裡,當我們呼叫 action 時,可以傳遞參數,這些參數就會存在 action.payload

addBy: (state, action) => {
state.value += action.payload;
}
  • 這裡 action.payload 代表的是我們 dispatch 時傳入的值。

Counter.js 內部:

dispatch(addBy(5));

這個 dispatch(addBy(5)) 實際上:

{
type: 'counter/addBy',
payload: 5
}
  • 這個物件會傳遞到 addByreducer,讓 action.payload 變成 5,然後 state.value += 5

最後當reducer 更新完 state.value 後,Redux 會:

  • 更新 Store(新的 state.value 變成 6)。
  • 通知所有訂閱該 state 的元件(React 會重新渲染 UI)。
  1. 建立計數器元件

第四步驟,我們在 Counter.js 中撰寫 React 元件:

import React, { useState } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { increment, decrement, addBy } from './store/store.jsx';

const Counter = () => {
const count = useSelector((state) => state.counter.value);
const dispatch = useDispatch();
const [inputValue, setInputValue] = useState(0);

return (
<div style={{ textAlign: 'center', marginTop: '50px' }}>
<h1>Counter: {count}</h1>
<button onClick={() => dispatch(increment())}>+1</button>
<button onClick={() => dispatch(decrement())}>-1</button>
<br /><br />
<input
type="number"
value={inputValue}
onChange={(e) => setInputValue(Number(e.target.value))}
/>
<button onClick={() => dispatch(addBy(inputValue))}>Add By</button>
</div>
);
};

export default Counter;

因為我們在 Counter.js 中用 useSelector() 取得 state.value

const count = useSelector((state) => state.counter.value);

當 Redux Store 更新 state.value 後,React 會偵測到 count 變動,並重新渲染 <h1>

<h1>Counter: {count}</h1>

例如: 畫面上的數字會從 5 → 6,使用者能看到變化!


補充一下:

當你使用 useSelector() 取得 state 時:

const count = useSelector((state) => state.counter.value);
  • state 代表整個 Redux Store
  • state.counter 代表 counterSlice
  • state.counter.value 取得 counterSlice 內的 value

今天假設你把 name: "counter" 改成 name: "myCounter"initialState: { count: 0 }改成initialState: { count: 0 },則useSelector() 也要改成:

const count = useSelector((state) => state.myCounter.count);
  1. 最後設定 Provider 並渲染應用

第五步驟,在 App.js 中:

import React from 'react';
import { Provider } from 'react-redux';
import store from './store/store.jsx';
import Counter from './Counter.jsx';

const App = () => {
return (
<Provider store={store}>
<Counter />
</Provider>
);
};

export default App;

這樣我們就完成了React-Redux最簡單的應用。建議讀者可以實際操作一次並了解流程。

留言
avatar-img
電資鼠 - 您的學習好夥伴
19會員
242內容數
在當今數位時代,電資領域人才需求爆發式成長,不論是前端網頁設計、嵌入式開發、人工智慧、物聯網還是軟硬體整合,這些技術都在改變世界。而掌握 C/C++、Python、數位邏輯、電路學與嵌入式開發等大學電資領域的課程,正是進入這個高薪、高需求產業的關鍵!
2025/03/05
在 React 中,useContext() 是一個 Hook,用來讓你在函式元件中輕鬆地存取 context 資料,避免繁瑣的 props 傳遞。以下是一步步的教學與示例程式碼。 透過本章學習,你將掌握 如何在 React 應用中運用 useContext() 管理全域狀態,提升開發效率!
2025/03/05
在 React 中,useContext() 是一個 Hook,用來讓你在函式元件中輕鬆地存取 context 資料,避免繁瑣的 props 傳遞。以下是一步步的教學與示例程式碼。 透過本章學習,你將掌握 如何在 React 應用中運用 useContext() 管理全域狀態,提升開發效率!
2025/03/05
在本章,我們將使用 React Hooks(useState、useEffect、useRef)來 開發一個碼錶 (Stopwatch) 應用。
2025/03/05
在本章,我們將使用 React Hooks(useState、useEffect、useRef)來 開發一個碼錶 (Stopwatch) 應用。
2025/03/05
透過本章學習,你將掌握 useRef() 的核心概念與最佳應用方式,提高 React 應用的效能與靈活性!
2025/03/05
透過本章學習,你將掌握 useRef() 的核心概念與最佳應用方式,提高 React 應用的效能與靈活性!
看更多
你可能也想看
Thumbnail
在 vocus 與你一起探索內容、發掘靈感的路上,我們又將啟動新的冒險——vocus App 正式推出! 現在起,你可以在 iOS App Store 下載全新上架的 vocus App。 無論是在通勤路上、日常空檔,或一天結束後的放鬆時刻,都能自在沈浸在內容宇宙中。
Thumbnail
在 vocus 與你一起探索內容、發掘靈感的路上,我們又將啟動新的冒險——vocus App 正式推出! 現在起,你可以在 iOS App Store 下載全新上架的 vocus App。 無論是在通勤路上、日常空檔,或一天結束後的放鬆時刻,都能自在沈浸在內容宇宙中。
Thumbnail
vocus 慶祝推出 App,舉辦 2026 全站慶。推出精選內容與數位商品折扣,訂單免費與紅包抽獎、新註冊會員專屬活動、Boba Boost 贊助抽紅包,以及全站徵文,並邀請你一起來回顧過去的一年, vocus 與創作者共同留下了哪些精彩創作。
Thumbnail
vocus 慶祝推出 App,舉辦 2026 全站慶。推出精選內容與數位商品折扣,訂單免費與紅包抽獎、新註冊會員專屬活動、Boba Boost 贊助抽紅包,以及全站徵文,並邀請你一起來回顧過去的一年, vocus 與創作者共同留下了哪些精彩創作。
Thumbnail
CSS 是控制網頁外觀的語言,應用於網頁設計、UI/UX 設計、電子商務和移動應用開發。主要使用者包括前端開發者、UI/UX 設計師和網頁設計師。CSS 的特性有樣式控制、層疊優先級、響應式設計及分離內容與樣式。
Thumbnail
CSS 是控制網頁外觀的語言,應用於網頁設計、UI/UX 設計、電子商務和移動應用開發。主要使用者包括前端開發者、UI/UX 設計師和網頁設計師。CSS 的特性有樣式控制、層疊優先級、響應式設計及分離內容與樣式。
Thumbnail
先從react開始: 其實市面上有許多前端框架像是react,angular,vue... 至於為什麼我會選擇react…
Thumbnail
先從react開始: 其實市面上有許多前端框架像是react,angular,vue... 至於為什麼我會選擇react…
Thumbnail
你好,在下最近在學習開發web,學了html css js,也得出一些心得,由於網路上已有許多教學,所以我會著重在如何開發出to do List,以及解釋我寫的程式碼。相關的教學我會直接貼網址。如果我有什麼地方出錯,或者是可以寫得更好,歡迎在下方留言,討論。 首先先介紹我的開發環境: 我用了vs
Thumbnail
你好,在下最近在學習開發web,學了html css js,也得出一些心得,由於網路上已有許多教學,所以我會著重在如何開發出to do List,以及解釋我寫的程式碼。相關的教學我會直接貼網址。如果我有什麼地方出錯,或者是可以寫得更好,歡迎在下方留言,討論。 首先先介紹我的開發環境: 我用了vs
Thumbnail
到底要用 ref 還是 reactive 是一個很常見的問題,不過現在官方文檔推薦使用 ref 就行,所以也不是甚麼大問題就是了。( •̀ ω •́ )✧ 所以 reactive 真的沒用用途了嗎?這篇文章來記錄一下 reactive 的用法。
Thumbnail
到底要用 ref 還是 reactive 是一個很常見的問題,不過現在官方文檔推薦使用 ref 就行,所以也不是甚麼大問題就是了。( •̀ ω •́ )✧ 所以 reactive 真的沒用用途了嗎?這篇文章來記錄一下 reactive 的用法。
Thumbnail
在程式任何地方都能修改各種react組件狀態的做法分享
Thumbnail
在程式任何地方都能修改各種react組件狀態的做法分享
Thumbnail
軟體系統的發展歷程大多相似,首重解決基本需求、提供操作介面,進而提升安全性、擴充功能、優化操作。
Thumbnail
軟體系統的發展歷程大多相似,首重解決基本需求、提供操作介面,進而提升安全性、擴充功能、優化操作。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News