import { useSession } from 'next-auth/react' import { LoginPage } from '@/client/components/index' const Homepage = () => { const session = useSession() if (session && session.data) { return ( <> <div>Homepage</div> </> ) } return <LoginPage /> } export default Homepage Básicamente, no quiero escribir el mismo modelo de Login & useSession() en cada página.
quiero algo como:
import { withAuth } from '@/client/components/index' const Homepage = () => { return ( <> <div>Homepage</div> </> ) } export default withAuth(Homepage) ¿O si es posible withAuthHook ?
Actualmente he hecho lo siguiente:
import React from 'react' import { useSession } from 'next-auth/react' import { LoginPage } from '@/client/components/index' export const withAuth = (Component: React.Component) => (props) => { const AuthenticatedComponent = () => { const session = useSession() if (session && session.data) { return <Component {...props} /> } return <LoginPage /> } return AuthenticatedComponent }Pero me sale un error:
El tipo de elemento JSX 'Componente' no tiene ninguna construcción ni firmas de llamadas.ts(2604)
Si uso React.ComponentType como se menciona en la respuesta a continuación, aparece un error que dice:
TypeError: (0, client_components_index__WEBPACK_IMPORTED_MODULE_0 _.withAuth) no es una función
Has probado:
export const withAuth = (Component: React.ComponentType) => (props) => { ...https://flow.org/en/docs/react/types/#toc-react-componenttype
Editar: Prueba así:
export const withAuth = (Component: React.ComponentType) => (props) => { const session = useSession() if (session && session.data) { return <Component {...props} /> } return <LoginPage /> } return AuthenticatedComponent}
La respuesta estaba oculta en los documentos . Tuve que especificar la siguiente función Auth en _app.tsx :
import { useEffect } from 'react' import { AppProps } from 'next/app' import { SessionProvider, signIn, useSession } from 'next-auth/react' import { Provider } from 'urql' import { client } from '@/client/graphql/client' import '@/client/styles/index.css' function Auth({ children }: { children: any }) { const { data: session, status } = useSession() const isUser = !!session?.user useEffect(() => { if (status === 'loading') return if (!isUser) signIn() }, [isUser, status]) if (isUser) { return children } return <div>Loading...</div> } interface AppPropsWithAuth extends AppProps { Component: AppProps['Component'] & { auth: boolean } } const CustomApp = ({ Component, pageProps: { session, ...pageProps } }: AppPropsWithAuth) => { return ( <SessionProvider session={session}> <Provider value={client}> {Component.auth ? ( <Auth> <Component {...pageProps} /> </Auth> ) : ( <Component {...pageProps} /> )} </Provider> </SessionProvider> ) } export default CustomApp Y en mi página real, tuve que especificar Component.auth como true :
const Homepage = () => { return ( <> <div>Homepage</div> </> ) } Homepage.auth = true export default HomepagePuede encontrar un buen resumen de lo que hace en https://simplernerd.com/next-auth-global-session