---
# System prepended metadata

title: Redux
tags: [React]

---

# Redux
###### tags: `React`

```javascript=
// 安裝 Redux（for React 使用）
npm install redux react-redux
```
### 什麼是 Redux
> Redux 是一個**全域的狀態管理**函式庫。透過建立一個且唯一的資料容器（**Store**），管理資料（以 object tree 的形式儲存的 **states**）。

![](https://i.imgur.com/sjBGhkt.png)

### 重要名詞
![](https://camo.githubusercontent.com/9de527b9432cc9244dc600875b46b43311918b59/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6d656469612d702e736c69642e65732f75706c6f6164732f3336343831322f696d616765732f323438343739302f415243482d5265647578322d657874656e6465642d7265616c2d6465636c657261746976652e676966)

| 重要名詞 | 解釋 |
| -------- | -------- |
| **Store**  | Globalized state  |
| **Action**  | describe what U want to do  |
| **Reducer**  | Action -> change state  |
| **Dispatch**  | Execute Action to Reducer  |

:::info
**Redux 工作流程：**
- 建立 Actions（檔案）
- 建立 Reducers（檔案）
- 建立 store & 設定 `<ProviderRedux>`
- 需要使用 state 的時候，使用 `useSelector` 取得。
- 需要變動 state 的時候，使用 `useDispatch` 發送 Action 給 Reducer。
:::

- **建立 Actions（物件）**
```javascript=
const add = (num) => {  // 如果需要傳遞參數
  return {
    type: "add",
    payload: num,  // 就要加個 payload 屬性
  };
};
```
- **建立 Reducers（函式）**
```javascript=
const Reducer1 = (state = 0, action) => { // 引入 state（設定預設） action
  switch (action.type) {  // 用 switch 判別傳入的 action 對應的方法
    case "add":
      return state + action.payload;
    case "subtract":
      return state - action.payload;
    default:  // switch 預設值
      return state;
  }
};

// 合併多個 reducer
import { combineReducers } from "redux";  // import combineReducers

const allReducer = combineReducers({
  Reducer1,
  Reducer2,
});
```
- **建立 Store & 設定範圍**
```javascript=
import {createStore} from "redux"
import { Provider } from "react-redux";

let myStore = createStore(allReducer);

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

### 相關 HOOK
#### useSelector 
> 取得 State
```javascript=
import {useSelector} from "react-redux"

const counter = useSelector(state => state.counter)
```

#### useDispatch
> 需要改變 State 時，需透過 `Dispatch` 傳遞 action（指令）給 Reducer 改變 Store 裡的 State
```javascript=
import { useDispatch } from "react-redux";

const dispatch = useDispatch();
dispatch(add(5)) // dispatch(action)
```
### 瀏覽器插件 Redux DevTools Extension
[安裝文件](https://github.com/zalmoxisus/redux-devtools-extension#usage)

### 其他說明
#### 到底要不要使用 Redux？
使用 Redux 會需要撰寫較多的程式碼，對於較小的專案，開發成本會顯得太高。
但當專案有一定規模，Redux 的狀態管理系統，可以更方便開發後的維護、測試、debug。
![](https://i.imgur.com/d1bm58H.png)
