简体   繁体   中英

How to use react hook in specific NextJS? (Firebase Authentication)

I have a nextjs app. I want to authenticate users with firebase. But I want some pages to client-side render and some pages to server-side render. But When I am using this Hook in _app.tsx all pages are rendered on the client side.

How can I use this hook on a specific page so that only that page renders on the client side?

_app.tsx

function MyApp({ Component, pageProps }: AppProps) {
  return (
    <UserAuthContentProvider>
      <Layout>
        <Component {...pageProps} />
      </Layout></UserAuthContentProvider>
  );
}

AuthContext Hook

export const auth = getAuth(app);
const AuthContext = createContext<any>({});
export const useAuthContextProvider = () => useContext(AuthContext);

export const UserAuthContentProvider = ({
    children,
}: {
    children: React.ReactNode;
}) => {
    const router = useRouter();
    const [user, setUser] = useState<User | null>(null);
    const [loading, setLoading] = useState(true);
    const [isUserAuthenticated, setIsUserAuthenticated] = useState(false);

    useEffect(() => {
        const unsubscribe = onAuthStateChanged(auth, (user) => {
            if (user) {
                setUser(user);
                setIsUserAuthenticated(true);
            } else {
                setUser(null);
                setIsUserAuthenticated(false);
            }
            setLoading(false);
        });
        return () => unsubscribe();
    });
};

const signUp = async (email: string, password: string) => {
    await createUserWithEmailAndPassword(auth, email, password).then((result) => {
        if (!result.user.emailVerified) {
            router.push("/verification");
        } else {
            router.push("/dashboard");
        }
    });
};

const logIn = async (email: string, password: string) => {
    await signInWithEmailAndPassword(auth, email, password).then((result) => {
        if (!result.user.emailVerified) {
            router.push("/verification");
        } else {
            router.push("/dashboard");
        }
    });
};

const logOut = async () => {
    setUser(null);
    await auth.signOut().finally(() => {
        router.push("/");
    });
};

return (
    <AuthContext.Provider
        value={{
            user,
            logIn,
            signUp,
            logOut,
            isUserAuthenticated,
        }}
    >
        {loading ? null : children}
    </AuthContext.Provider>
);

If you look in the NextJS Data Fetching docs here they go over which hook to use to trigger which pages you want to render and where.

If you want certain pages to server render you use getServerSideProps if you want to do a regular React runtime client render you can use getInitialProps and if you want to Static Site Generate at server build time you use getStaticProps . Depending on which hook you use on which Page is what determines the NextJS rendering strategy.

In development mode NextJS always uses SSR for developer experience so if you want to test you will need to run npm run build && npm run start .

If you only want a certain page to do one of the rending strategies maybe you can put the rending hook with the strategy you want as a noop on that page.

Since that hook is in the _app it will always run during all strategies so the pages always have that data hydrated. Depending on the strategy will depend on how often that data updates or when its referenced during the build cycle.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM