Home > OS >  NEXTJS: Invalid hook call
NEXTJS: Invalid hook call

Time:12-02

I'm using the new middleware in nextjs 12 and am trying to add authentication using firebase.

But when i try to use the hook useAuthState it's giving me an error saying: "Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:

  1. You might have mismatching versions of React and the renderer (such as React DOM)
  2. You might be breaking the Rules of Hooks
  3. You might have more than one copy of React in the same app See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem. null"

I have not made any changes in the app other than creating 2 components both in pages directory

login.js and _middleware.js

here is my _middleware.js

import { NextResponse } from "next/server";
// import firebase from "firebase"
import { initializeApp } from "firebase/app";
import "firebase/auth";
import { getAuth } from "firebase/auth";
import { useAuthState } from "react-firebase-hooks/auth";

initializeApp({
  apiKey: "AIzaSyAG1uIhyO0czQtkNNz7mz5kb-0EIfmv4IQ",
  authDomain: "clone-3-471b2.firebaseapp.com",
  projectId: "clone-3-471b2",
  storageBucket: "clone-3-471b2.appspot.com",
  messagingSenderId: "954111481882",
  appId: "1:954111481882:web:66abeb0cea36775ece19a3",
});

const auth = getAuth();

export async function middleware(req) {
  const [user] = useAuthState(auth);
  const { pathname } = req.nextUrl;

  if (!user) {
    return NextResponse.redirect("/login");
  }

  return NextResponse.next();
}

Here is my login.js

function login() {
  const signInWithGoogle = () => {
    console.log("Clicked!");
  };

  return (
    <div>
      <button onClick={signInWithGoogle}>Sign in with google</button>
    </div>
  );
}

export default login;

And here's my package.json

{
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start"
  },
  "dependencies": {
    "firebase": "^9.5.0",
    "next": "^12.0.4",
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "react-firebase-hooks": "^4.0.1"
  },
  "devDependencies": {
    "autoprefixer": "^10.2.6",
    "postcss": "^8.3.5",
    "tailwindcss": "^2.2.4"
  }
}

CodePudding user response:

According to React docs

Don’t call Hooks from regular JavaScript functions. Instead, you can:

✅ Call Hooks from React function components.
✅ Call Hooks from custom Hooks (we’ll learn about them on the next page).

So you're using hooks inside regular Javascript function below.

export async function middleware(req) { // this is regular JavaScript function
  const [user] = useAuthState(auth); // here you're using hook
  const { pathname } = req.nextUrl;

  if (!user) {
    return NextResponse.redirect("/login");
  }

  return NextResponse.next();
}

Solution for you case might be

import React, { useEffect } from "react";
import { NextResponse } from "next/server";
import { useAuthState } from "react-firebase-hooks/auth";

function login() {
  const [user] = useAuthState(auth); // here you're using hook
  const { pathname } = req.nextUrl;
  
  useEffect(() => {
    if (!user) {
      return NextResponse.redirect("/login");
    }
  
    return NextResponse.next();
  }, [user]);

  const signInWithGoogle = () => {
    console.log("Clicked!");
  };


  return (
    <div>
      <button onClick={signInWithGoogle}>Sign in with google</button>
    </div>
  );
}

export default login;

Don't forget to import requried imports in your component

CodePudding user response:

Following nextjs documentation:

next/server

The next/server module provides several exports for server-only helpers, such as Middleware.

Middleware

Middleware enables you to use code over configuration. This gives you full flexibility in Next.js, because you can run code before a request is completed. Based on the user's incoming request, you can modify the response by rewriting, redirecting, adding headers, or even streaming HTML.

The middleware is not a react component and cannot use hooks.

  • Related