如何在 nextjs 组件中使用 next-auth?
Posted
技术标签:
【中文标题】如何在 nextjs 组件中使用 next-auth?【英文标题】:How do I use next-auth within a nextjs component? 【发布时间】:2022-01-22 12:39:29 【问题描述】:我正在尝试将我的应用程序拆分为多个组件,并且我正在尝试创建一个仪表板组件,但是,我该如何在组件中实现 next-auth,以前我有 getServerSideProps
,但是因为这个是我做不到的组件。
这是我的组件
import
SearchIcon,
BellIcon,
UserCircleIcon,
ChevronDownIcon,
UserIcon,
LogoutIcon
from '@heroicons/react/outline';
import signOut from 'next-auth/client';
export default function Navigation(...session)
return (
<>
<div className="py-6 px-8 lg:h-16 lg:flex justify-between items-center bg-blue-700 text-white">
<div className="flex-1">
<div className="lg:pr-4 lg:py-4">
<label htmlFor="search" className="sr-only">
Search
</label>
<div className="relative">
<div className="pointer-events-none absolute inset-y-0 left-0 pl-3 flex items-center">
<SearchIcon className="h-5 w-5 text-white" aria-hidden="true" />
</div>
<input
id="search"
name="search"
className="block w-full bg-blue-800 border border-blue-800 rounded-md py-2 pl-10 pr-3 text-sm placeholder-white focus:outline-none focus:ring-1 focus:ring-white focus:border-white sm:text-sm"
placeholder="Search"
type="search"
/>
</div>
</div>
</div>
<div className="relative flex items-center justify-center mt-8 lg:mt-0">
<div className="relative mr-6">
<BellIcon className="w-5" />
<small className="text-xs absolute -top-1 -right-2 -mt-2 bg-red-500 rounded-full py-0.5 px-1.5">
1
</small>
</div>
<details className="relative">
<summary className="flex items-center">
<UserCircleIcon className="w-5 mr-2" />
<h2>
session.user.firstname session.user.lastname
</h2>
<ChevronDownIcon
className="ml-2 flex-shrink-0 h-4 w-4 text-blue-200"
aria-hidden="true"
/>
</summary>
<div className="w-full mt-4 pb-4 absolute shadow-lg flex flex-col justify-center px-2 space-y-1 bg-blue-700">
<Link href="/dashboard/myprofile">
<a className="bg-blue-800 text-white hover:bg-blue-600 flex items-center px-2 py-2 text-sm font-medium rounded-md">
<UserIcon className="w-5 h-5 mr-2" />
Profile
</a>
</Link>
<Link href="#">
<a
onClick=signOut
className="bg-blue-800 text-white hover:bg-blue-600 flex items-center px-2 py-2 text-sm font-medium rounded-md">
<LogoutIcon className="w-5 h-5 mr-2" />
Sign out
</a>
</Link>
</div>
</details>
</div>
</div>
</>
);
目前我得到的是以下内容
TypeError: Cannot read properties of undefined (reading 'firstname')
编辑#1
这是我的_app.js
[已更新]
import Head from 'next/head';
import Provider from 'next-auth/client';
// assets
import '../styles/global.css';
import '../javascripts/app.js';
// components
import Footer from './components/Footer';
function MyApp( Component, pageProps )
return (
<>
<Head>
<meta name="theme-color" content="#1E40AF" />
</Head>
<section className="flex flex-col min-h-screen">
<Provider session=pageProps.session>
<Component ...pageProps className="flex-1" />
</Provider>
</section>
<Footer />
</>
);
export default MyApp;
【问题讨论】:
您是否尝试过在组件中使用useSession
?
@juliomalves 我已经尝试过了,但我无法让会话通过
您没有在您的_app
文件中使用SessionProvider
吗?
@juliomalves 我已将我的 app.js 文件添加为编辑。
如果您没有从 s-s-r 传递会话,您可能需要在 useEffect
中使用 getSession()
来检索它。
【参考方案1】:
为了解决这个问题,我做了以下操作
_app.js
- 现在使用提供者在所有页面之间共享会话。
import Head from 'next/head';
import Provider from 'next-auth/client';
// assets
import '../styles/global.css';
import '../javascripts/app.js';
// components
import Footer from './components/Footer';
function MyApp( Component, pageProps )
return (
<>
<Head>
<meta name="theme-color" content="#1E40AF" />
</Head>
<section className="flex flex-col min-h-screen">
<Provider session=pageProps.session>
<Component ...pageProps className="flex-1" />
</Provider>
</section>
<Footer />
</>
);
export default MyApp;
对于组件,我现在有以下内容
import
SearchIcon,
BellIcon,
UserCircleIcon,
ChevronDownIcon,
UserIcon,
LogoutIcon
from '@heroicons/react/outline';
import useSession, signOut from 'next-auth/client';
import Link from 'next/link';
export default function Navigation()
const [session, loading] = useSession()
return (
<>
<div className="py-6 px-8 lg:h-16 lg:flex justify-between items-center bg-blue-700 text-white">
<div className="flex-1">
<div className="lg:pr-4 lg:py-4">
<label htmlFor="search" className="sr-only">
Search
</label>
<div className="relative">
<div className="pointer-events-none absolute inset-y-0 left-0 pl-3 flex items-center">
<SearchIcon className="h-5 w-5 text-white" aria-hidden="true" />
</div>
<input
id="search"
name="search"
className="block w-full bg-blue-800 border border-blue-800 rounded-md py-2 pl-10 pr-3 text-sm placeholder-white focus:outline-none focus:ring-1 focus:ring-white focus:border-white sm:text-sm"
placeholder="Search"
type="search"
/>
</div>
</div>
</div>
<div className="relative flex items-center justify-center mt-8 lg:mt-0">
<div className="relative mr-6">
<BellIcon className="w-5" />
<small className="text-xs absolute -top-1 -right-2 -mt-2 bg-red-500 rounded-full py-0.5 px-1.5">
1
</small>
</div>
<details className="relative">
<summary className="flex items-center">
<UserCircleIcon className="w-5 mr-2" />
session &&
<h2>
session.firstname session.lastname
</h2>
<ChevronDownIcon
className="ml-2 flex-shrink-0 h-4 w-4 text-blue-200"
aria-hidden="true"
/>
</summary>
<div className="w-full mt-4 pb-4 absolute shadow-lg flex flex-col justify-center px-2 space-y-1 bg-blue-700">
<Link href="/dashboard/myprofile">
<a className="bg-blue-800 text-white hover:bg-blue-600 flex items-center px-2 py-2 text-sm font-medium rounded-md">
<UserIcon className="w-5 h-5 mr-2" />
Profile
</a>
</Link>
<Link href="#">
<a
onClick=signOut
className="bg-blue-800 text-white hover:bg-blue-600 flex items-center px-2 py-2 text-sm font-medium rounded-md">
<LogoutIcon className="w-5 h-5 mr-2" />
Sign out
</a>
</Link>
</div>
</details>
</div>
</div>
</>
);
【讨论】:
以上是关于如何在 nextjs 组件中使用 next-auth?的主要内容,如果未能解决你的问题,请参考以下文章
Nextjs:如何使用具有多个值的 ContextAPI,所有这些值都需要从子组件中更新
如何将道具从组件传递到 NextJS 中的 getServerSideProps()?