[React]toolkitとredux

<h2>toolkitとは</h2>
Reduxをより簡単に使用するためのツール。<br>
既存のReduxの問題点を補完してくれます。<br>
以前はaction type、action creator、action別reducerをそれぞれ定義する方式だったため、
構成に必要なものを全て他のファイルにそれぞれ作成するため、新しいactionとreducerを定義する度にコードに追加しなければならない煩わしさが生じることがある。

<h2>toolkit install</h2>

```
npm install @reduxjs/toolkit react-redux
```

<h2>toolkitを使ってreduxを実装</h2>

```react:/src/app/store.js
import { configureStore } from "@reduxjs/toolkit";
import counterReducer from "../features/counter/counterSlice";
export default configureStore({
    reducer: {
        counter: counterReducer,
    },
});
```
configureStoreはReducerから返還された新しいstateをstoreというオブジェクトにまとめて管理するところです。

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

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <Provider store={store}>
      <App />
    </Provider>
  </React.StrictMode>
);
```
アプリ内のコンポーネントのどこからでもストアにアクセスできるように定義します。
<br>


```react:/src/features/counter/Counter.jsx
import React from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { increment, decrement, incrementByAmount} from './counterSlice';

export default function Counter() {
    // storeに保存されているstate！reducerにて更新されたnew state！！〜！
    const count = useSelector((state) => state.counter.value)
    const dispatch = useDispatch();
  return (
      <div>
          <div>
              {/* dispatchにはactionを指定 */}
              <button onClick={() => dispatch(increment())}>increment</button>
              <span>{count}</span>
              <button onClick={() => dispatch(decrement())}>decrement</button>
              {/* 5はpayload */}
              <button onClick={() => dispatch(incrementByAmount(5))}>incrementByAmount</button> 
          </div>
      </div>
  )
}
```
dispatch()の引数にactionを設定しています。
前回で話した通り、dispatch()はreducerにactionを伝達してくれる関数です。
incrementとdecrementとincrementByAmount　これらのactionは
counterSlice.jsの中で定義したactionとなります。
incrementByAmountは引数を渡していますが、これがpayloadといいます。
payloadはactionに渡す具体的な値です。
<br>

```react:/src/features/counter/counterSlice.js
import { createSlice } from "@reduxjs/toolkit";

export const counterSlice = createSlice({
    // module name
    name: 'counter',
    // module initial state value
    initialState: {
        value: 0,
    },
    // reducer
    reducers: {
        // action1
        increment: (state) => {
            // action logic
            state.value += 1
        },
        // action2
        decrement: (state, action) => {
            // action logic
            state.value -= 1
        },
        // action3
        incrementByAmount: (state, action) => {
            // action logic
            state.value += action.payload;
        },
    },
});

export const { increment, decrement, incrementByAmount } = counterSlice.actions;
// counterSliceはstore.jsのcounterReducer！
export default counterSlice.reducer;
```
redux-toolkitのcreateSliceにてaction type、action creator、reducerなどすべての機能を1つのファイルの中で作成できます。reducerのキー名にてactionが自動作成されます！

以下の開発ツールモードにて、中身を確認すると理解しやすいかと思います。
「decrement action」の時
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3097775/11595cb5-204a-df70-6876-369e1958bab4.png)
「incrementByAmount action」の時
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3097775/b1c09f41-1cee-5b47-834f-6a25914afafa.png)
Counter.jsxからdispatch(action名)が実行してきて、reducer()に到着します。
actionはtypeとpayloadをもち、typeは「counterSliceのname/action名」となります。
payloadはactionの引数値になります。Counter.jsxからとすると「dispatch(incrementByAmount(5)の5」が該当します。
decrementは引数なして送ってきたため、undefined!