Skip to main content

什麼是 Redux?

Redux 是一個 JavaScript 狀態管理庫,幫助你將應用程式的狀態集中管理。它基於三個核心原則:

  1. 單一狀態來源:整個應用程式的狀態儲存在一個物件(state)中,稱為 store。

  2. 狀態唯讀:不能直接修改狀態,只能透過發送 action 來描述要進行的改變。

  3. 使用純函數來更新狀態:透過 reducer 函數(純函數)來處理 action 並更新狀態。

Redux 通常與 React 一起使用,透過 react-redux 將 Redux 的狀態連接到 React 元件。


步驟 1:安裝 Redux 和相關套件

假設你正在使用 React 專案,以下是如何設定 Redux 的步驟。

1.1 安裝依賴

在終端機中,進入你的專案資料夾,執行以下命令來安裝 Redux 和 react-redux:

npm install redux react-redux
  • redux:核心 Redux 庫,提供狀態管理的功能。

  • react-redux:讓 Redux 與 React 整合的工具,提供 Provider 和 hooks(如 useSelector 和 useDispatch)。

1.2 確認安裝

檢查 package.json,應該會看到以下依賴:

"dependencies": {
"redux": "^5.0.1",
"react-redux": "^9.0.4"
}

步驟 2:建立 Redux Store

Redux 的核心是 store,它儲存應用程式的狀態。我們需要建立一個 store,並定義初始狀態和 reducer 函數。

2.1 建立 Reducer

Reducer 是一個純函數,負責根據 action 更新狀態。假設我們要管理一個簡單的計數器狀態(counter)。

在專案的 src 資料夾中,建立一個新資料夾 redux,然後新增一個檔案 counterReducer.js:

// src/redux/counterReducer.js
const initialState = {
count: 0
};

const counterReducer = (state = initialState, action) => {
switch (action.type) {
case 'INCREMENT':
return {
...state,
count: state.count + 1
};
case 'DECREMENT':
return {
...state,
count: state.count - 1
};
default:
return state;
}
};

export default counterReducer;

說明

  • initialState:定義初始狀態,這裡是一個物件,包含 count 屬性,初始值為 0。

  • counterReducer:根據 action 的 type 決定如何更新狀態。

    • 如果 action.type 是 'INCREMENT',則將 count 加 1。

    • 如果 action.type 是 'DECREMENT',則將 count 減 1。

    • 其他情況下,返回原始狀態(不變)。

  • 使用展開運算子 (...state) 確保不直接修改原始狀態,而是返回新物件。

2.2 建立 Store

在 src/redux 資料夾中,新增一個檔案 store.js:

// src/redux/store.js
import { createStore } from 'redux';
import counterReducer from './counterReducer';

const store = createStore(counterReducer);

export default store;

說明

  • createStore 是 Redux 提供的函數,用來建立 store。

  • 將 counterReducer 傳入 createStore,讓 store 知道如何處理狀態。

  • 匯出 store,供其他地方使用。


步驟 3:將 Redux 連接到 React

我們需要使用 react-redux 的 Provider 元件,將 store 提供給 React 應用程式。

3.1 修改主應用程式檔案

假設你的主應用程式檔案是 src/index.js,修改它如下:

// src/index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import { Provider } from 'react-redux';
import store from './redux/store';
import App from './App';

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

說明

  • 從 react-redux 匯入 Provider 元件。

  • 將 store 傳給 Provider 的 store 屬性,讓所有 React 元件都能存取 Redux 的狀態。

  • App 是你的主元件,現在它和它的子元件都可以使用 Redux。


步驟 4:建立 React 元件並使用 Redux

現在我們建立一個簡單的計數器元件,來展示如何使用 Redux 的狀態和 dispatch action。

在 src 資料夾中,建立一個新檔案 Counter.js:

// src/Counter.js
import React from 'react';
import { useSelector, useDispatch } from 'react-redux';

const Counter = () => {
// 使用 useSelector 從 store 取得狀態
const count = useSelector((state) => state.count);
// 使用 useDispatch 取得 dispatch 函數
const dispatch = useDispatch();

return (
<div>
<h1>計數器: {count}</h1>
<button
onClick={() => dispatch({ type: 'INCREMENT' })}
>
加 1
</button>
<button
onClick={() => dispatch({ type: 'DECREMENT' })}
>
減 1
</button>
</div>
);
};

export default Counter;

說明

  • useSelector:用來從 store 取得狀態。這裡我們取出 state.count。

  • useDispatch:用來取得 dispatch 函數,讓我們可以發送 action。

  • 按下「加 1」按鈕時,發送 { type: 'INCREMENT' } 的 action。

  • 按下「減 1」按鈕時,發送 { type: 'DECREMENT' } 的 action。

  • 當 action 發送後,counterReducer 會處理並更新狀態,元件會自動重新渲染,顯示新的 count 值。

4.1 在 App 元件中使用 Counter

修改 src/App.js,加入 Counter 元件:

// src/App.js
import React from 'react';
import Counter from './Counter';
import './App.css';

function App() {
return (
<div className="App">
<header className="App-header">
<Counter />
</header>
</div>
);
}

export default App;

步驟 5:執行應用程式

  1. 確保你的專案已經安裝了所有依賴(npm install)。

  2. 執行以下命令啟動開發伺服器:

    npm start
  3. 開啟瀏覽器,應該會看到一個簡單的計數器頁面,顯示「計數器: 0」,並有「加 1」和「減 1」兩個按鈕。

  4. 點擊按鈕,應該可以看到計數器數值變化。


步驟 6:進階技巧(非必要,但有助於理解)

以下是一些常見的 Redux 使用技巧,幫助你更好地管理程式碼。

6.1 使用 Action Creators

為了讓程式碼更乾淨,可以將 action 物件封裝到函數(action creators)中。

在 src/redux 資料夾中,新增一個檔案 actions.js:

// src/redux/actions.js
export const increment = () => ({
type: 'INCREMENT'
});

export const decrement = () => ({
type: 'DECREMENT'
});

然後修改 Counter.js,使用這些 action creators:

// src/Counter.js
import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { increment, decrement } from './redux/actions';

const Counter = () => {
const count = useSelector((state) => state.count);
const dispatch = useDispatch();

return (
<div>
<h1>計數器: {count}</h1>
<button onClick={() => dispatch(increment())}>
加 1
</button>
<button onClick={() => dispatch(decrement())}>
減 1
</button>
</div>
);
};

export default Counter;

說明

  • increment 和 decrement 是 action creators,負責產生 action 物件。

  • 使用 action creators 讓程式碼更易於維護和測試。

6.2 結合多個 Reducer

如果你的應用程式有更多狀態,可以使用 combineReducers 來管理多個 reducer。

假設你新增一個管理使用者資訊的 reducer,在 src/redux 中新增 userReducer.js:

// src/redux/userReducer.js
const initialState = {
name: '訪客'
};

const userReducer = (state = initialState, action) => {
switch (action.type) {
case 'SET_NAME':
return {
...state,
name: action.payload
};
default:
return state;
}
};

export default userReducer;

然後修改 store.js,結合多個 reducer:

// src/redux/store.js
import { createStore, combineReducers } from 'redux';
import counterReducer from './counterReducer';
import userReducer from './userReducer';

const rootReducer = combineReducers({
counter: counterReducer,
user: userReducer
});

const store = createStore(rootReducer);

export default store;

說明

  • combineReducers 將多個 reducer 合併成一個 root reducer。

  • 狀態結構變成 { counter: { count: 0 }, user: { name: '訪客' } }

  • 在元件中,使用 useSelector 時需指定子狀態,例如 useSelector((state) => state.counter.count)useSelector((state) => state.user.name)


步驟 7:除錯與工具

為了方便除錯,建議安裝 Redux DevTools 瀏覽器擴充功能。

7.1 安裝 Redux DevTools

  1. 在 Chrome 或 Firefox 中安裝 Redux DevTools 擴充功能。

  2. 修改 store.js,啟用 Redux DevTools:

    // src/redux/store.js
    import { createStore, combineReducers } from 'redux';
    import counterReducer from './counterReducer';
    import userReducer from './userReducer';

    const rootReducer = combineReducers({
    counter: counterReducer,
    user: userReducer
    });

    // 啟用 Redux DevTools
    const store = createStore(
    rootReducer,
    window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
    );

    export default store;

說明

  • window.REDUX_DEVTOOLS_EXTENSION 啟用 DevTools,允許你在瀏覽器中檢視狀態變化和 action 歷史。

7.2 使用 DevTools

  1. 開啟瀏覽器的開發者工具(F12)。

  2. 找到 Redux 標籤,你可以看到:

    • 當前狀態。

    • 每個 action 的詳細資訊。

    • 可以「回溯」到之前的狀態,方便除錯。


總結

你現在已經學會如何在 React 專案中使用 Redux!以下是主要步驟的回顧:

  1. 安裝 redux 和 react-redux。

  2. 建立 reducer 和 store。

  3. 使用 Provider 將 store 連接到 React。

  4. 在元件中使用 useSelector 和 useDispatch 來存取狀態和發送 action。

  5. (可選)使用 action creators 和 combineReducers 管理更複雜的狀態。

  6. 使用 Redux DevTools 除錯。