はじめに
この記事では、Reactプロジェクトにおいて仮登録メールのリンクをクリックしたあとのページ到達時に完了トーストを表示したいが、トースト通知が2回表示される問題に遭遇し、その解決策を共有します。
※トーストはreact-hot-toast
を使用しております。
エラー内容
エラー文はでませんでしたが、現象としてはトースト通知が2回、重複して表示されるというものです。
試したこと(現状)
- コンポーネントの再レンダリングの確認
- 他のコード部分での
toast
関数の呼び出し確認 - SSR(Server-Side Rendering)の影響を考慮
原因
SSRの環境で、クライアントサイドとサーバーサイドの両方でトースト表示のコードが実行されてしまっていた。
解決策
コードをクライアントサイドでのみ実行するように修正することで、この問題を解決しました。具体的には、以下のようにuseState
とuseEffect
を組み合わせて、クライアントサイドで実行されていることを確認し、トーストを表示しました。
※SSRのページコンポーネント箇所は特に必要ないと思うので、ここには記載してません。
import React, { useEffect, useState } from 'react';
import toast, { Toaster } from 'react-hot-toast';
const Register: React.FC = () => {
const [isClient, setIsClient] = useState(false);
useEffect(() => {
// クライアントサイドでのみ実行
setIsClient(true);
if (isClient) {
toast.success('メール認証を行い仮登録が完了しました!');
}
}, [isClient]); // 依存配列に isClient を含める
return (
<>
<Toaster />
{/* ...他のコード... */}
</>
);
};
export default Register;
結果
上記の修正により、トースト通知が2回表示される問題は解決し、トーストはクライアントサイドでのみ表示されるようになりました。
終わりに
この問題の解決を通じて、SSRの環境でのクライアントサイドとサーバーサイドのコード実行の違い、そしてReactのuseState
とuseEffect
を組み合わせた解決法を習得しました。
ふむ、なるほど!でした。