如何在特定的NextJS中使用React钩子?(FireBase身份验证)

vfhzx4xs  于 2022-10-01  发布在  其他
关注(0)|答案(1)|浏览(135)

我有一个Nextjs应用程序。我想使用Firebase对用户进行身份验证。但是我想要一些页面在客户端呈现,一些页面在服务器端呈现。但是,当我在_app.tsx中使用这个Hook时,所有页面都呈现在客户端。

如何在特定页面上使用此钩子,以便只在客户端呈现该页面?

_app.tsx

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

授权上下文钩子

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>
);
wbrvyc0a

wbrvyc0a1#

如果您查看NextJS数据获取文档here,它们将使用哪个钩子来触发您希望呈现哪些页面以及呈现在哪里。

如果您希望某些页面在服务器上呈现,您可以使用getServerSideProps;如果您希望进行常规React运行时客户端呈现,您可以使用getInitialProps;如果您希望在服务器构建时生成静态站点,则可以使用getStaticProps。根据您在哪个Page上使用的挂钩,决定了NextJS呈现策略。

在开发模式下,NextJS总是使用SSR来获得开发人员体验,所以如果您想要测试,您将需要运行npm run build && npm run start

如果您只想让某个页面执行其中一种呈现策略,也许您可以将呈现钩子与您想要的策略一起放在该页面上。

由于该挂钩位于_app中,因此它将在所有策略期间始终运行,因此页面始终保持该数据的水合状态。具体取决于策略,具体取决于数据更新的频率或构建周期中引用数据的时间。

相关问题