[Next.js]React-Toastifyを使ってみた

## はじめに
Next.jsにチャレンジしていく過程をメモ/備忘録として記録していきます。
同じようにこれから始める方の参考となればと思います。

## やりたいこと
React-Toastifyを使ってみたい

## 環境
下記のDocker開発環境にて行います。

https://qiita.com/mkthrkw/items/30115c9ac54c2204faef


## React-Toastifyについて

公式のplaygroundで遊ぶとイメージを掴みやすいのですが、
表示位置やテーマなど簡単に設定できる、Toast　UIのライブラリです。
オートクローズなどのオプション機能もあって感動です！！

https://fkhadra.github.io/react-toastify/introduction/

### Next.jsの導入について

```ToastContainer```を、上位コンポーネントに配置しておけば、配下のコンポーネントから呼び出しが出来るというものです。
Next.jsのApp routerでいうと、一番最上位の```app/layout.tsx```においておけばどこからでも呼び出せるということになります。

ただ、```ToastContainer```はクライアントコンポーネント、```app/layout.tsx```はサーバーコンポーネントなので、そのまま置くだけというわけにはいきませんでした。

```app/layout.tsx```のProps.childrenを、```ToastContainer```を配置したクライアントコンポーネント```ToastProvider```でラップするという方法で行なっていきます。

こちらを参考にさせていただきました（ありがとうございます）

https://zenn.dev/koyabluetech/articles/78f6a4caf096e2


### 1. まずはインストール
```shell
npm install --save react-toastify
```

### 2.クライアントコンポーネント```ToastProvider```を作成

```app/layout.tsx```の```Props.children```を包み込むためのクライアントコンポーネントです。
```ToastContainer```にデフォルト値が設定できるので公式のplagroundを参考に設定しました。

```typescript:ToastProvider.tsx
"use client";

import "react-toastify/dist/ReactToastify.css";
import { Flip, ToastContainer } from "react-toastify";

export default function ToastProvider(
  { children }: {children: React.ReactNode;}) {

  return (
    <>
      {children}
      <ToastContainer
        toastClassName={"rounded-lg min-w-96 text-center"}
        position="bottom-center"
        autoClose={3000}
        hideProgressBar={false}
        newestOnTop={false}
        closeOnClick
        rtl={false}
        pauseOnFocusLoss
        draggable
        pauseOnHover
        theme="colored"
        transition={Flip}
      />
    </>
  );
}
```

### ３.```ToastProvider```でをラップ
```app/layout.tsx```内の```Props.childrenを```を先ほど作成した```ToastProvider```の中に入れます。
これでどこからでも呼び出せるようになりました。

```typescript:app/layout.tsx
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "./globals.css";
import ToastProvider from '@/components/layouts/ToastProvider'

const inter = Inter({ subsets: ["latin"] });

export const metadata: Metadata = {
  title: "Some title",
  description: "This is example page.",
};

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <html lang="ja">
      <body className={inter.className}>
        <ToastProvider>
          {children}
        </ToastProvider>
      </body>
    </html>
  );
}
```


### 4.呼び出しテスト

動くのかテストしてみます。
もちろん、ToastContainerがクライアントコンポーネントですので、呼び出しもクライアントコンポーネントからじゃないと動きません。
下記ボタンだけ置いて、デフォルト設定のまま呼び出しテスト。

```typescript:page.tsx
'use client'

import { toast } from "react-toastify";

export default function Page() {
  return (
    <div className="flex flex-col justify-center items-center gap-8 w-screen h-screen">
      <button className="btn btn-wide" onClick={() => toast("Default Notification !")}>
          Default Toast
        </button>
        <button className="btn btn-wide btn-success" onClick={() => toast.success("Success Notification !")}>
          Success Toast
        </button>
        <button className="btn btn-wide btn-error" onClick={() => toast.error("Error Notification !")}>
          Error Toast
        </button>
    </div>
  );
}
```

ボタンを押すとちゃんと思い通りにToastが表示されました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3680973/2d452441-b62a-0643-3037-bf40f945ccdd.png)



## さいごに
すごく簡単にトーストを導入できました。
これからも便利なライブラリをどんどん導入していきたいと思います。



## 参考

https://zenn.dev/koyabluetech/articles/78f6a4caf096e2

https://fkhadra.github.io/react-toastify/introduction