useReducer + useContext vs Redux

---
###### tags: `Redux`, `React`, `基本知識`
<br>
## 前提
在學習程式裡,通常讀懂了功能,記住了各別使用的方式,卻不知道要用在哪裡,使用的時機點是什麼時候。
這些都是經驗累積,或者由經驗者帶著操作和分享才順利學習到的。
至於這次分享是我在一次的面試線下作業裡用到,也花了點時間去整理(怪不得我在寫得時候覺得還蠻熟悉的),然後這文章就誕生了。
## useContext + useReducer

### 什麼是 useContext?
- useContext 是 React的一個 Hook ,用於跨層級共享狀態或數據用的。它的主要作用是避免過多的 props 傳遞(Prop Drilling)
1. Context 物件:
- 用來保存可以被多個物件共享的數據。
- 透過 Provider 和 Consumer 實現數據的傳遞與使用。
2. 跨層級共享數據:
- 父組件可以通過 Provider 提供數據,子組件通過 useContext 獲取。
```
const value = useContext(MyContext);
```
- 這應該是在人生第一次嘗試跨多層傳遞資訊的時候,最常會用的 hook,API拿到了就丟進去,然後在某個Component 或者 page再抓出來。 當然現在上線的某些輕量級專業也會用的到。
### 什麼是 useReducer?
- useReducer 也是 React 的一個 Hook,用於處理複雜和統整煩瑣的功能,它特別適合用於多層次的狀態更新,或者當多個行為(actions) 會影響同一狀態時。
1. Reducer函數:
- 用一個純函數,負責根據當前的狀態和觸發的action,返回新的狀態。
- 簡化多個 setState 操作,將所有邏輯集中管理。
2. 狀態與派發:
- state: 當前的狀態
- dispatch:一個函數,用來傳遞 action, 觸發狀態更新,可以想像為 移動版的 setState。
```
const [state, dispatch] = useReducer(reducer, initialState);
// reducer 就是 所有的action
// initialState 就是 初始值。
```

### 一起使用的 例子:
1. 建立 Context 和 Reducer
```
import React, { createContext, useReducer, useContext } from 'react';
const AppContext = createContext();
const initialState = { count: 0 };
const reducer = (state, action) => {
switch (action.type) {
case 'INCREMENT':
return { count: state.count + 1 };
case 'DECREMENT':
return { count: state.count - 1 };
default:
return state;
}
};
```
2. 創建 Provider 組件
```
export const AppProvider = ({ children }) => {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<AppContext.Provider value={{ state, dispatch }}>
{children}
</AppContext.Provider>
);
};
```
3. 消費數據
```
const Counter = () => {
const { state, dispatch } = useContext(AppContext);
return (
<div>
<p>Count: {state.count}</p>
<button onClick={() => dispatch({ type: 'INCREMENT' })}>Increment</button>
<button onClick={() => dispatch({ type: 'DECREMENT' })}>Decrement</button>
</div>
);
};
```
4. 回到 app.jsx:
```
const App = () => (
<AppProvider>
<Counter />
</AppProvider>
);
export default App;
```
### 適用場景的選擇:
- 只需要共享數據:使用 useContext
- 如:主題切換、用戶數據。
- 需要處理複雜的邏輯:使用 useReducer
- 如:表單、多步操作的狀態管理。
- 需要跨組件共享且有複雜邏輯:結合 useReducer 和 useContext
- 如:全局的應用狀態(類似 Redux 功能)。
---
## Redux:
經過上面的 useReducer 和 useContext的介紹,是否覺得跟Redux似曾相識?

redux 是一個套件,提到 middleware ,大家應該會優先想到 Redux,zustand 吧?比起 useReducer 和 useContext,Redux看起來能做的事情更多,例如 query 也可以。
對於Redux來說,它具備了 useContext 和 useReducer 的功能,但在便利下,也需要做很多前置設定。

### 適用場景:

## 總結:
useReducer 和 useContext 是React 內部元件,不需要安裝就可以直接,可以它們的全局管理和傳遞資料是有限的。適合處理簡單的邏輯和較小的專案。
Redux 適合大型應用的全局狀態管理,功能強大,可擴展性高,尤其適用於需要中間件或全局狀態的場景,還有很多很多的tools可以擴充其功能。
希望這篇文章可以幫助大家在未來專案選擇裡,做出最好的決定。
願這文章有幫助你學習!我們下篇文章再見! PEACE!
