如何使用 Next.js Link 组件传递数据而不在 URL 中显示数据?

问题描述 投票:0回答:1

我目前正在开发 Next.js 应用程序,我需要在页面之间导航,同时传递一些数据而不在 URL 中公开它。我知道 Next.js 中的 Link 组件允许我在页面之间导航,但我不确定如何在不将数据附加到 URL 的情况下实现此目的。

import Link from 'next/link';

const SourceComponent = () => {
  const dataToPass = { key: 'value' };

  return (
    <Link href="/target-page" passHref>
      <a>{/* Some content */}</a>
    </Link>
  );
};

在此示例中,数据未传递到目标页面。我想访问目标页面上的“dataToPass”。

我还尝试使用 router.push 以编程方式导航:

import Link from 'next/link';

import { useRouter } from 'next/router';

const SourceComponent = () => {
  const router = useRouter();
  const dataToPass = { key: 'value' };

  const handleClick = () => {
    router.push({
      pathname: '/target-page',
      query: { data: JSON.stringify(dataToPass) }, // This exposes the data in the URL
    });
  };
  return (
    <button onClick={handleClick}>Go to Target Page</button>
  );
};

在这种情况下,我注意到数据仍然附加到 URL 中。

谢谢您的帮助!

reactjs next.js components nextjs14
1个回答
0
投票

答案取决于您的用例以及您想要传递的数据类型。一种方法是使用 React Context API 在页面之间共享数据。

假设您将 NextJS 与 App Router 一起使用,您需要创建一个上下文提供程序组件并用它包装您的应用程序。

// src/providers/EnvironmentProvider.tsx

'use client';

import {
  ReactNode,
  createContext,
  useContext,
  useMemo
} from 'react';


type EnvironmentContextType = {
  data: any;
  setData: (params: any) => void;
};

const ENVIRONMENT_CONTEXT_DEFAULT_VALUES: EnvironmentContextType = {
  data: {},
  setData: () => {}
};

const EnvironmentContext = createContext(ENVIRONMENT_CONTEXT_DEFAULT_VALUES);

export const useEnvironment = () => useContext(EnvironmentContext);

type EnvironmentProviderProps = {
  children: ReactNode;
};

export const EnvironmentProvider = ({
  children
}: EnvironmentProviderProps) => {
  const [data, setData] = useState<any>({});

  const values: EnvironmentContextType = useMemo(() => ({
    data,
    setData
  }), []);

  return ( <
    EnvironmentContext.Provider value={
      values
    }>{
      children
    }<
    /EnvironmentContext.Provider>
  );
};

// src/app/layout.tsx

import { EnvironmentProvider } from '@/providers/EnvironmentProvider';

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <head>
        <link rel="manifest" href="/manifest.json" />
      </head>

      <body>
        <EnvironmentProvider>
          {children}
        </EnvironmentProvider>
      </body>
    </html>
  );
}

考虑用正确的类型替换

any
(或者如果使用 JS 则删除任何类型)。

更新了

SourceComponent
TargetComponent

import Link from 'next/link';

import { useRouter } from 'next/router';

import { useEnvironment } from '@/providers/EnvironmentProvider';

const SourceComponent = () => {
  const router = useRouter();
  const { setData } = useEnvironment();
  const dataToPass = { key: 'value' };

  const handleClick = () => {
    setData(dataToPass);

    router.push({
      pathname: '/target-page',
    });
  };
  return (
    <button onClick={handleClick}>Go to Target Page</button>
  );
};

const TargetComponent = () => {
  const { data } = useEnvironment();

  return (
    <h1>{data.key}</h1>
  );
};

来自 Vercel 的更详细指南 使用 React Context 与 Next.js 进行状态管理

© www.soinside.com 2019 - 2024. All rights reserved.