Next.jsでmicroCMS上のデータをRTK Queryで取得してSwiperでカルーセルを作成 

関わっているプロジェクトでNext.js,microCMS,RTK Query,Swiperでカルーセルが実装されていたので自分でも実装してみました。


タイトルが長くなっていますが流れ的には,
1. microCMSでブログ記事作成　
1. RTK QueryでmicroCMSのデータ取得
1. Swiperでカルーセルを作成
 
てな感じで紹介していきます！

# microCMSでブログ記事を作成
簡単にダミーのブログ記事を作成しました。
|blogId|title|imgBlog|blogText|
|:---:|:---:|:--:|:--:|
|ブログID|タイトル|ブログ画像|ブログ本文|
### .envにAPIとbaseURLを記載
Next.jsにある.envに記載していきます。
環境変数をクライアントサイドでしようするには、先頭に**NEXT_PUBLIC_** をつける必要があります。
```.env
NEXT_PUBLIC_API_KEY=*******
NEXT_PUBLIC_MICRO_CMS_BASE_URL = *******
```

microCMS側の準備は終了です！
# RTK Queryの準備
RTKQueryとは、DataFetchingとCachingToolです。
詳しくは[公式ドキュメント](https://redux-toolkit.js.org/rtk-query/overview)や[こちらの記事](https://qiita.com/kana-wwib/items/2928c395608aa4318acf)を参考にしてください。

使用する前に下記コマンドを実行してください。
```
npm i -S @reduxjs/toolkit
```

### API Sliceを作成
microCMSのデータを取得できるようにAPIキーをリクエストヘッダにセットします。
```typescript:base-cms.ts
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
export const blogApi = createApi({
  reducerPath: "blogApi",
  baseQuery: fetchBaseQuery({
    baseUrl: process.env.NEXT_PUBLIC_MICRO_CMS_BASE_URL,
    prepareHeaders: (headers) => {
      if (process.env.NEXT_PUBLIC_API_KEY) {
        headers.set("X-MICROCMS-API-KEY", process.env.NEXT_PUBLIC_API_KEY);
      }
      return headers;
    },
  }),
  keepUnusedDataFor: 600,
  endpoints: () => ({}),
});
```

### QueryEndpointを定義
injectEndpointsを使用すればendpoint毎にファイルを分割することができます！
```typescript:rtk-swiper.ts
import { blogApi } from "../cms/base-cms";
export type blogType = {
  title: string;
  blogText: string;
  imgBlog: {
    url: string;
    height: number;
    width: number;
  };
  blogId: string;
};
export type blogListType = {
  contents: blogType[];
  totalCount: number;
  offset: number;
  limit: number;
};

export const blogApiCms = blogApi.injectEndpoints({
  endpoints: (builder) => ({
    getAllBlog: builder.query<blogListType, string>({
      query: () => "swiper-blog?limit=100&fields=title,imgBlog,blogText,blogId",
    }),
  }),
});

export const { useGetAllBlogQuery } = blogApiCms;
```
ues + endpointsで定義した名前(getAllBlog) + Queryでカスタムフックが作成できます。(useGetAllBlogQuery)
実際のコンポーネントでの使用方法は**siwperでカルーセル作成**で説明します。

microCMSで作成したAPIの末尾にクエリを指定することで取得するデータを色々整形できます。
今回は使用したクエリのみ紹介します。詳しく知りたい方は[こちら](https://document.microcms.io/content-api/get-list-contents)へ
- limit
取得件数を指定　デフォルト値は10。
- fields
カンマ区切りで取得する要素を指定できる。今回だとtitle,imgBlog,blogText,blogIdを指定している。

### storeの設定
middlewareを設定することで、キャッシングやRTK Queryの便利機能が使えるようになります。
```typescript:rtk-store.ts
import { configureStore } from "@reduxjs/toolkit";
import { setupListeners } from "@reduxjs/toolkit/query";
import { blogApi } from "../rtk/cms/base-cms";

export const store = configureStore({
  reducer: {
    [blogApi.reducerPath]: blogApi.reducer,
  },
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware().concat(blogApi.middleware),
});
setupListeners(store.dispatch);
export type RootState = ReturnType<typeof store.getState>;
```
storeの設定は以上です！
次にSwiperでカルーセルを作成していきます。
## Swiperでカルーセルを作成
詳細を知りたい方は[公式ドキュメント](https://swiperjs.com/react)を読んでみてください！


まずはswiperをインストールします。
```
npm i swiper
```
次に実際に書いたコードを載せます。
```typescript:swiper.tsx
import { Swiper, SwiperSlide } from "swiper/react";
import { Navigation, Pagination, Autoplay } from "swiper";
import { useGetAllBlogQuery } from "../../rtk/services/rtk-swiper";
import { Box, Heading, Text, Flex, Image } from "@chakra-ui/react";
import { blogType } from "../../rtk/services/rtk-swiper";

export const SwiperSample = () => {
  const { data: swiperData, isLoading } = useGetAllBlogQuery();
  return (
    <>
      {!isLoading && (
        <Swiper
          modules={[Navigation, Pagination, Autoplay]}
          slidesPerView={1}
          loop={true}
          navigation
          pagination={{ clickable: true }}
          autoplay={{ delay: 3000 }}
        >
          {swiperData?.contents.map((item: blogType) => (
            <SwiperSlide key={item.blogId}>
              <Box cursor={"pointer"}>
                <Flex
                  width={"70%"}
                  mx={"auto"}
                  mb={"4px"}
                  alignItems={"center"}
                >
                  <Image
                    src={item.imgBlog.url}
                    alt="blog-title"
                    width={"100px"}
                    height={"100px"}
                    objectFit={"cover"}
                  />
                  <Heading>{item.title}</Heading>
                </Flex>
                <Text width={"80%"} mx={"auto"}>
                  {item.blogText}
                </Text>
              </Box>
            </SwiperSlide>
          ))}
        </Swiper>
      )}
    </>
  );
};

```
デザインはChakraUIを使用しています。興味のある方は[公式ドキュメント](https://chakra-ui.com/)を読んでみてください。
```
const { data: swiperData, isLoading } = useGetAllBlogQuery();
```
この部分で先ほどRTK Queryで作成したカスタムフックを使用しています。

上のコードを大まかに説明すると
1. "swiper/react"より{Swiper,SwiperSlide}をエクスポート
2. SwiperSlideに表示したいコンテンツをラップし、さらに外からSwiperでラップする。

という感じです。 

swiperには便利なモジュールがあり、今回使用したものを紹介します。
- Navigation
サイドにある矢印ボタン
- Pagenation
スライド下にあるボタン
- Autoplay
スライドが自動に切り替わるモジュール

今回使用したpropsについても記載しておきます。
- slidesPerView
スライドで表示できる枚数を設定できる
- loop
スライド移動をループさせることができる

ここまでの内容で下の画像のようなカルーセルが作成できるようになります！![スクリーンショット 2022-06-06 16.44.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2696080/98aeb360-8788-12f3-28e1-9c5af0ed36ff.png)

## まとめ
microCMSがとても便利！
RTK Queryの基本的な使い方を学ぶことができました！
カルーセルを作成したい時、swiperを使用すれば簡単に作成できます！

今後も気になったフロント周りの技術について紹介できたらと思っています！