我目前正在开发 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 中。
谢谢您的帮助!
答案取决于您的用例以及您想要传递的数据类型。一种方法是使用 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 进行状态管理。