1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

"Cannot update a component () while rendering a different component ()."エラー解消法

Posted at

はじめに

Cannot update a component () while rendering a different component ().のエラーが出ました。

Cannot update a component (`Router`) while rendering a different component (`Private`). To locate the bad setState() call inside `Private`, follow the stack trace as described in https://react.dev/link/setstate-in-render

原因

レンダー中に別コンポーネントの状態変更が発生していることが原因でした。

以下参照です。

React コンポーネントは、レンダー中に他のコンポーネントに副作用を起こしてはいけません。
レンダー中に setState を呼び出すことはサポートされていますが同じコンポーネントに対してのみ可能です。

解決方法

該当部分にuseEffectを使うことで、レンダリング後に副作用として実行するようにしました。

修正前
レンダー中にPrivateコンポーネントでrouter.pushを実行してしまっています。

page.tsx
const Private = ({ children }: { children: React.ReactNode }) => {
  const router = useRouter();

    if (!loading) {
      if (isSignedIn) {
        return children;
      } else {
       //該当部分
        router.push(`/signin`);
      }
    } else {
      return <></>;
    }
  };
  return (
    <AuthContext.Provider
      value={{ currentUser, setCurrentUser, isSignedIn, setIsSignedIn }}
    >
      <Private>
        <p>Homeページです</p>
      </Private>
    </AuthContext.Provider>
  );

修正後
レンダリング中に router.pushを実行しないように、useEffectでラップしています。依存配列を明示的に指定し、不要なレンダーを防ぎます。

page.tsx
const Private = ({ children }: { children: React.ReactNode }) => {
  const router = useRouter();

  useEffect(() => {
    if (!loading && !isSignedIn) {
      router.push("/signin");
    }
  }, [loading, isSignedIn, router]); // 依存配列を明確にする

  if (loading) {
    return <></>; // ローディング中は何も表示しない
  }

  if (!isSignedIn) {
    return null; // リダイレクト中はコンテンツをレンダリングしない
  }

  return <>{children}</>;
  };
  return (
    <AuthContext.Provider
      value={{ currentUser, setCurrentUser, isSignedIn, setIsSignedIn }}
    >
      <Private>
        <p>Homeページです</p>
      </Private>
    </AuthContext.Provider>
  );

下記も参考になります。

おわりに

エラーは解消しましたが、エフェクトの多用はアンチパターンとして取り上げられているので、使うべきかどうかは迷いどころです。
用法に注意したいところです。

1
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?