---
# System prepended metadata

title: Redux Tutorial (with Redux Toolkit)
tags: ['Javascript, React']

---

#  Redux Tutorial (with Redux Toolkit)

###### tags: `Javascript, React`

# 介紹 Redux 

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


假設上面兩個框框代表兩個 component

* 上面的 state 要追蹤數字呈現
* 下面的 state 要追蹤增加的數字

這個時候要把 "增加的數字" 這個 state 丟給 "數字呈現的" state 使用，這樣跨 component 的 state 傳輸狀況就可以使用到 Redux。

> Redux 是一個 react component 以外的的一個存在，並且你可以在其內部儲存變數供其他的 component 來操作，可以更便利的管理 state 而不用一直傳遞 props ，在大型專案下非常實用 


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

以這個例子來看可以發現右邊藍色處是 redux ，他儲存了 count ，然後 increment, decrement 可以直接對其操作，就不需要在那邊傳遞變數進來進去了

# 實例介紹

本篇操作範例會使用 redux toolkit:
[範例程式碼](https://codesandbox.io/s/modest-https-h7x3m?file=/src/redux/counter.js:125-126)

Redux toolkit官網:
[Redux Quick Start](https://redux-toolkit.js.org/tutorials/quick-start)


## 第一步當然是安裝

需要先到 terminal 做安裝

Install Redux Toolkit and React-Redux

`npm install @reduxjs/toolkit react-redux`


## 接下來新增 redux 資料夾以及建立設定檔

可以參考 [連結](https://redux-toolkit.js.org/tutorials/quick-start#create-a-redux-store)

1. 建立 redux 資料夾讓吃進去所有的 state
![](https://i.imgur.com/Z5lR7pc.png)

2. 並且建立設定檔進去
![](https://i.imgur.com/JGJpXnt.png)


## 下一步前往最外層的 index.js 設定 tag

可以參考 [連結](https://redux-toolkit.js.org/tutorials/quick-start#provide-the-redux-store-to-react)

1. 首先必須先引入 `{store} {Provider}` 

2. 可以看到範例處會使用 Provider tag 包裹住原本的 root component
![](https://i.imgur.com/MT9NRgL.png)

## redux 如何操作

分成三部分

1. State 就是紀錄起來的 state 
2. Action 會呼叫要操作 State 的 component
3. Reducer 就會真的操作剛剛呼叫的 component 並且更新 State

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


## 使用 redux toolkit 的好處

可以以一個更簡潔的方式在 createSlice 內建立好上面三個部分

```javascript=
export const counterSlice = createSlice({
  name: "counter", // 這邊的命名可以讓這個變數跟其他的使用 component 做出區別 (比方說其他的可能命名 shopping cart)
  initialState: {
    count: 0 // 初始值 ，這邊的 count 是可以任意改的為了符合操作這邊使用 count
  },
  reducers: {
    increment: (state) => {
      state.count += 1;
    },
    decrement: (state) => {
      state.count -= 1;
    },
    incrementByAmount: (state, action) => {
      state.count += action.payload;
    }
  }
});

// 輸出的部分也得把三個 Action 輸出加上 reducer(這邊使用解構擷取三個 action)
export const { increment, decrement, incrementByAmount } = counterSlice.actions;

export default counterSlice.reducer;

```

## 把剛剛設好的 counterSlice 放進去設定檔 store 裡面

只要每一次有新的 reducer 產生就必須重新放進去一次 store 設定檔

這邊把剛剛的 counterReducer 引入檔案以及加進去 reducer 內部，就可以被其他的 component 操作瞜

```javascript=
import { configureStore } from "@reduxjs/toolkit";
import counterReducer from "./counter"; // 這邊可以自行命名但就是要引入剛剛的 counterSlice 檔案

export default configureStore({
  reducer: {
    counter: counterReducer // counter 這邊可以自行命名
     // user: userReducer 這邊是範例
  }
});
```


## 開始把註冊好的 reducer 放進去 component 做使用

這邊是主要操作加減部分的程式碼

1. 首先要引入 { useDispatch, useSelector } 為了可以選取 store 中的註冊好的 counter: counterReducer ，使用方式如下使用 useSelector 帶入 state 參數後 .counter 及可以操作 reducer
```javascript=
const { count } = useSelector((state) => state.counter);
```
2. 接下來要來拉出 actions 使用必須使用 useDispatch

```javascript=
const dispatch = useDispatch();
```
3. 接下來在 onClick 處填入相對應的 aciton

比較特別的是第三個有放入參數用來對應 reducer 內部的 action.payload

```javascript=
incrementByAmount: (state, action) => {
      state.count += action.payload;
    }
```

```javascript=
<button onClick={() => dispatch(increment())}>increment</button>
<button onClick={() => dispatch(decrement())}>decrement</button>
<button onClick={() => dispatch(incrementByAmount(33))}>Increment by 33</button>
```

