ReduxのcreateSliceについてわからなかったので調べた




Reduxを含めたReactプロジェクトに途中からジョインしました。
ですが現行のソースコードがまったくわからない...。

おおよその雰囲気は単語の端々をかいつまんで翻訳することで把握できましたが、
そもそもReduxやReactを深くは知らない。

ですので調べてきました！
ChatGPTがな！



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1678228/a09a3209-d6c5-c436-2345-6c21895833e9.png)



## reduxのcreateSliceについて教えて？

```ts
import { createSlice } from '@reduxjs/toolkit';

const counterSlice = createSlice({
  name: 'counter',
  initialState: 0,
  reducers: {
    increment: (state) => state + 1,
    decrement: (state) => state - 1,
    incrementByAmount: (state, action) => state + action.payload,
  },
});

export const { increment, decrement, incrementByAmount } = counterSlice.actions;
export default counterSlice.reducer;
```


<p><code>createSlice</code>は、Redux Toolkitの一部であり、Reduxの<code>createReducer</code>や<code>createAction</code>を組み合わせたものです。これにより、簡単にReduxのstoreの状態を更新するためのリデューサーとアクションを作成できます。</p><p><code>createSlice</code>は、以下のように使用します。</p><pre><div class="bg-black rounded-md mb-4"><div class="flex items-center relative text-gray-200 bg-gray-800 px-4 py-2 text-xs font-sans justify-between rounded-t-md"><span>javascript</span><button class="flex ml-auto gap-2"><svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" class="h-4 w-4" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"></path><rect x="8" y="2" width="8" height="4" rx="1" ry="1"></rect></svg>Copy code</button></div><div class="p-4 overflow-y-auto"><code class="!whitespace-pre hljs language-javascript"><span class="hljs-keyword">import</span> { createSlice } <span class="hljs-keyword">from</span> <span class="hljs-string">'@reduxjs/toolkit'</span>;

```typescript
import { createSlice } from '@reduxjs/toolkit';

const counterSlice = createSlice({
  name: 'counter',
  initialState: 0,
  reducers: {
    increment: (state) => state + 1,
    decrement: (state) => state - 1,
    incrementByAmount: (state, action) => state + action.payload,
  },
});

export const { increment, decrement, incrementByAmount } = counterSlice.actions;
export default counterSlice.reducer;
```

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> { increment, decrement, incrementByAmount } = counterSlice.<span class="hljs-property">actions</span>;
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> counterSlice.<span class="hljs-property">reducer</span>;
</code></div></div></pre><p>この例では、<code>createSlice</code>には3つの引数があります。</p><ul><li><code>name</code>は、スライスの名前を表します。</li><li><code>initialState</code>は、スライスの初期状態を表します。</li><li><code>reducers</code>は、スライスに関するアクションを定義するオブジェクトです。各アクションは、現在の状態を変更するための関数です。</li></ul><p>上記の例では、3つのアクションが定義されています。<code>increment</code>と<code>decrement</code>アクションは、状態を1ずつ増減させるための単純な関数です。<code>incrementByAmount</code>アクションは、<code>action.payload</code>で指定された値だけ状態を増やします。</p><p>最後に、<code>createSlice</code>は、アクションとリデューサーを含むオブジェクトを返します。このオブジェクトを使用して、Redux storeにスライスを追加することができます。また、アクションを直接エクスポートして、コンポーネント内で使用することもできます。</p>


## まとめると

- sliceはReactでいうStateのうちの一つ
- createSliceで作られたオブジェクトは操作された結果である「値」と「それに対する操作」と「初期値`initialState`」を持つ
- 「値に対する操作」は`reducers`で辞書形式でたくさんの関数がまとめられている



## ReduxでAPI操作したい



```ts
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
import axios from 'axios';

// APIリクエストを送信する非同期アクションを定義する
export const fetchData = createAsyncThunk('data/fetchData', async () => {
  const response = await axios.get('/api/data');
  return response.data;
});

// スライスを作成する
const dataSlice = createSlice({
  name: 'data',
  initialState: {
    items: [],
    loading: false,
    error: null,
  },
  reducers: {},
  extraReducers: {
    // リクエストが開始されたときの処理
    [fetchData.pending]: (state) => {
      state.loading = true;
    },
    // リクエストが成功したときの処理
    [fetchData.fulfilled]: (state, action) => {
      state.loading = false;
      state.items = action.payload;
    },
    // リクエストが失敗したときの処理
    [fetchData.rejected]: (state, action) => {
      state.loading = false;
      state.error = action.error.message;
    },
  },
});

// コンポーネントからAPIリクエストを送信するための関数を定義する
export const fetchAndStoreData = () => {
  return (dispatch) => {
    dispatch(fetchData());
  };
};

export default dataSlice.reducer;
```

<div class="markdown prose w-full break-words dark:prose-invert light"><p>APIとのデータ連携は、フロントエンドアプリケーションにとって非常に重要な要素です。Reduxを使うことで、APIとのデータ連携を効率的に行うことができます。</p><p>一般的に、ReduxアプリケーションでAPIとのデータ連携を行うには、以下の手順が必要です。</p><ol><li>APIリクエストを送信するアクションを定義する</li><li>アクションがデータを取得した場合、ステートを更新するリデューサーを定義する</li><li>コンポーネントからアクションをディスパッチするための関数を定義する</li><li>Redux Thunkミドルウェアを使って非同期API呼び出しを実行する</li></ol><p>以下は、例としてReduxの<code>createSlice</code>を使って、APIとのデータ連携を行うコードの一例です。</p><pre><div class="bg-black rounded-md mb-4"><div class="flex items-center relative text-gray-200 bg-gray-800 px-4 py-2 text-xs font-sans justify-between rounded-t-md"><span>javascript</span><button class="flex ml-auto gap-2"><svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" class="h-4 w-4" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"></path><rect x="8" y="2" width="8" height="4" rx="1" ry="1"></rect></svg>Copy code</button></div><div class="p-4 overflow-y-auto"><code class="!whitespace-pre hljs language-javascript"><span class="hljs-keyword">import</span> { createSlice, createAsyncThunk } <span class="hljs-keyword">from</span> <span class="hljs-string">'@reduxjs/toolkit'</span>;
<span class="hljs-keyword">import</span> axios <span class="hljs-keyword">from</span> <span class="hljs-string">'axios'</span>;



```ts
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
import axios from 'axios';

// APIリクエストを送信する非同期アクションを定義する
export const fetchData = createAsyncThunk('data/fetchData', async () => {
  const response = await axios.get('/api/data');
  return response.data;
});

// スライスを作成する
const dataSlice = createSlice({
  name: 'data',
  initialState: {
    items: [],
    loading: false,
    error: null,
  },
  reducers: {},
  extraReducers: {
    // リクエストが開始されたときの処理
    [fetchData.pending]: (state) => {
      state.loading = true;
    },
    // リクエストが成功したときの処理
    [fetchData.fulfilled]: (state, action) => {
      state.loading = false;
      state.items = action.payload;
    },
    // リクエストが失敗したときの処理
    [fetchData.rejected]: (state, action) => {
      state.loading = false;
      state.error = action.error.message;
    },
  },
});

// コンポーネントからAPIリクエストを送信するための関数を定義する
export const fetchAndStoreData = () => {
  return (dispatch) => {
    dispatch(fetchData());
  };
};

export default dataSlice.reducer;
```




<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> dataSlice.<span class="hljs-property">reducer</span>;
</code></div></div></pre><p>上記の例では、<code>createAsyncThunk</code>関数を使って非同期APIリクエストを送信するためのアクション<code>fetchData</code>を定義し、<code>extraReducers</code>オブジェクトを使用してアクションに対応するリデューサーを定義しています。また、APIリクエストを送信するための関数<code>fetchAndStoreData</code>を定義して、コンポーネントから呼び出すことができるようにしています。</p><p>このように、Reduxを使ってAPIとのデータ連携を行うことができます。</p></div>




## まとめると

- `extraReducers`をつかって外部APIと非同期通信する関数を作成すればいい感じになる


### extraReducersって何？

<p><code>extraReducers</code>は、他のスライスや外部のアクションに対して、Reduxのステートを更新するためのリデューサーを定義するために使用されます。<code>extraReducers</code>内で定義されたアクションに対するリデューサーは、通常のスライスのアクションと同じように、自動的に生成されたReduxのアクションクリエーターによってディスパッチされます。</p>

**簡単に言うと、非同期で外部APIを呼ぶときにいい感じにしてくれるってことだな！**

http://www.code-magagine.com/?p=13509