简体   繁体   English

如何在 nextjs 组件中使用 next-auth?

[英]How do I use next-auth within a nextjs component?

I'm trying too split my application into multiple components, and I'm trying to create a dashboard component, however, how do I go about implementing next-auth within the component, previously I had getServerSideProps but as this is a component I can't do that.我正在尝试将我的应用程序拆分为多个组件,并且我正在尝试创建一个仪表板组件,但是,我如何 go 关于在组件中实现下一个身份验证,以前我有getServerSideProps但因为这是一个组件,我可以不要那样做。

Here is my component这是我的组件

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>
    </>
  );
}

Currently what I'm getting is the following目前我得到的是以下

TypeError: Cannot read properties of undefined (reading 'firstname')

edit #1编辑#1

Here is my _app.js [UPDATED]这是我的_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;

To fix this I did the following为了解决这个问题,我做了以下

_app.js - Now using provider to share the session across all pages. _app.js - 现在使用提供程序在所有页面上共享 session。

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;

and for the component I now have the following对于组件,我现在有以下内容

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>
    </>
  );
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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