0

I was making an app using NextJS, TailwindCSS, Firebase and It is working 100% correctly on local host but on deploying on Vercel, I get the following error :

15:18 Error: React Hook "useRouter" is called conditionally. React Hooks must be called in the exact same order in every component render. react-hooks/rules-of-hooks 17:39 Error: React Hook "useDocumentOnce" is called conditionally. React Hooks must be called in the exact same order in every component render. react-hooks/rules-of-hooks

enter image description here

I am not able to understand why I get this error when deploying my app to Vercel.Maybe it's something related to redirect link in google API console

Here's my [id].js file :

import TextEditor from "../../components/TextEditor";
import Button from "@material-tailwind/react/Button";
import Icon from "@material-tailwind/react/Icon";
import { useRouter } from "next/dist/client/router";
import { db } from "../../firebase";
import { useDocumentOnce } from "react-firebase-hooks/firestore";
import { getSession, signOut, useSession } from "next-auth/client";
import Login from "../../components/Login";

function Doc() {
  const [session, loading] = useSession();
  console.log(session);
  if (!session) return <Login />;

  const router = useRouter();
  const { id } = router.query;
  const [snapshot, loadingSnapshot] = useDocumentOnce(
    db.collection("userDocs").doc(session.user.email).collection("docs").doc(id)
  );

  // Redirect if user tries to access a URL they do not have access to...
  if (!loadingSnapshot && !snapshot?.data()?.fileName) {
    // Filename will not be present if the user doesnt have access...
    router.replace("/");
  }

  return (
    <div>
      <header className="flex justify-between items-center p-3 pb-1">
        <span onClick={() => router.push("/")} className="cursor-pointer">
          <Icon name="description" size="5xl" color="blue" />
        </span>
        <div className="flex-grow px-2">
          <h2 className="text-lg text-left">{snapshot?.data()?.fileName}</h2>
          <div className="flex items-center text-sm -ml-1 h-8 text-gray-600 space-x-1">
            <p className="option">File</p>
            <p className="option">Edit</p>
            <p className="option">View</p>
            <p className="option">Insert</p>
            <p className="option">Format</p>
            <p className="option">Tools</p>
          </div>
        </div>

        <Button
          color="lightBlue"
          buttonType="filled"
          size="regular"
          className="hidden md:!inline-flex h-10"
          rounded={false}
          block={false}
          iconOnly={false}
          ripple="light"
        >
          <Icon name="people" size="md" /> SHARE
        </Button>

        <img
          onClick={signOut}
          className="cursor-pointer h-10 w-10 rounded-full ml-2"
          src={session.user.image}
          alt=""
        />
      </header>
      <TextEditor />
    </div>
  );
}

export default Doc;

export async function getServerSideProps(context) {
  const session = await getSession(context);

  return {
    props: {
      session,
    },
  };
}
1
  • Try passing null to useDocumentOnce() if the session is not defined. Then you can move all the hook calls above if (!session) return <Login />;. Commented Feb 12, 2022 at 18:02

1 Answer 1

0

You have early return before calling useDocumentOnce on line

if (!session) return <Login />

Which is not good as the error says. You should make sure that you always render the same amount of hooks on each render. In your case you are calling 3 hooks. But if session is not defined you only render 1 hook. That is the problem you have to resolve.

Sign up to request clarification or add additional context in comments.

4 Comments

On changing the position of the return <Login />, I get the error session not defined
TypeError: Cannot read properties of null (reading 'user')
Please check updated answer
I got what you are trying to say. My no of hooks depend on a condition but I am actually stucked here. useDocumentOnce requires session which is another hook. So inorder for the session to first load you can see what I did in the end const session = await getSession(context);. If you suggest any changes I should make for the code to work, that would do wonders to me

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.