快速入門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
留言分享你的想法!
avatar-img
電資鼠 - 您的學習好夥伴
9會員
215內容數
在當今數位時代,電資領域人才需求爆發式成長,不論是前端網頁設計、嵌入式開發、人工智慧、物聯網還是軟硬體整合,這些技術都在改變世界。而掌握 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
介紹朋友新開的蝦皮選物店『10樓2選物店』,並分享方格子與蝦皮合作的分潤計畫,註冊流程簡單,0成本、無綁約,推薦給想增加收入的讀者。
Thumbnail
介紹朋友新開的蝦皮選物店『10樓2選物店』,並分享方格子與蝦皮合作的分潤計畫,註冊流程簡單,0成本、無綁約,推薦給想增加收入的讀者。
Thumbnail
當你邊吃粽子邊看龍舟競賽直播的時候,可能會順道悼念一下2300多年前投江的屈原。但你知道端午節及其活動原先都與屈原毫無關係嗎?這是怎麼回事呢? 本文深入探討端午節設立初衷、粽子、龍舟競渡與屈原自沉四者。看完這篇文章,你就會對端午、粽子、龍舟和屈原的四角關係有新的認識喔。那就讓我們一起解開謎團吧!
Thumbnail
當你邊吃粽子邊看龍舟競賽直播的時候,可能會順道悼念一下2300多年前投江的屈原。但你知道端午節及其活動原先都與屈原毫無關係嗎?這是怎麼回事呢? 本文深入探討端午節設立初衷、粽子、龍舟競渡與屈原自沉四者。看完這篇文章,你就會對端午、粽子、龍舟和屈原的四角關係有新的認識喔。那就讓我們一起解開謎團吧!
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
軟體系統的發展歷程大多相似,首重解決基本需求、提供操作介面,進而提升安全性、擴充功能、優化操作。
Thumbnail
前言 現在的前端需求已經越來越高,要考慮HTML及CSS的切版美觀程度,以及React以及Flutter所提出的元件(Componet、widget)觀念,也就是將元件模組化,使元件可以更動態的被程式運行,而不用靜態的客製化每一個介面。開發一個好的元件可以提升整體的開發速度,讓任何使用元件的開發者
Thumbnail
前言 現在的前端需求已經越來越高,要考慮HTML及CSS的切版美觀程度,以及React以及Flutter所提出的元件(Componet、widget)觀念,也就是將元件模組化,使元件可以更動態的被程式運行,而不用靜態的客製化每一個介面。開發一個好的元件可以提升整體的開發速度,讓任何使用元件的開發者
Thumbnail
前端開發者常會遇到需要網頁素材的情況,雖然在公司中都可能有可以配合的平面設計師或是UIUX設計師,但在這個多工高效的時代不免也需要前端開發者也可以處理簡單的設計,也可提升設計審美或與設計師溝通的能力。 然而前端開發者也算是擁有設計師的天賦,透過程式碼來完成平面設計,將網頁的每個介面都視為平面設計,
Thumbnail
前端開發者常會遇到需要網頁素材的情況,雖然在公司中都可能有可以配合的平面設計師或是UIUX設計師,但在這個多工高效的時代不免也需要前端開發者也可以處理簡單的設計,也可提升設計審美或與設計師溝通的能力。 然而前端開發者也算是擁有設計師的天賦,透過程式碼來完成平面設計,將網頁的每個介面都視為平面設計,
Thumbnail
這是一個介紹React Text Wrap Balancer套件的文章,主要內容包括套件的使用方式,常見的實作方式和一些注意事項。文章內容較長,內容大概是在介紹套件的使用方法、使用技巧和注意事項。
Thumbnail
這是一個介紹React Text Wrap Balancer套件的文章,主要內容包括套件的使用方式,常見的實作方式和一些注意事項。文章內容較長,內容大概是在介紹套件的使用方法、使用技巧和注意事項。
Thumbnail
React Props - React 白話文運動。這一篇則會針對 React 語法進一步做講解, 前幾篇也學會了如何建立一個 React 元件,並且學會了元件之間有父子元件的關係。這篇會介紹 React Props 的概念,包含了:React 元件宣告、React Props。
Thumbnail
React Props - React 白話文運動。這一篇則會針對 React 語法進一步做講解, 前幾篇也學會了如何建立一個 React 元件,並且學會了元件之間有父子元件的關係。這篇會介紹 React Props 的概念,包含了:React 元件宣告、React Props。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News