You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NextJS 14中使用router.push无URL直接传对象的问题求助

Next.js 14 不通过URL传递数据的解决方案

你遇到的问题核心是:App Router 中的 next/navigation 模块里,router.push 的第二个参数没有 query 选项,且 useSearchParams 只能读取URL上的显式查询参数,所以你之前的写法无法拿到数据。下面是几种无需通过URL传递对象的可行方案:

方案1:使用路由自带的 state 参数(最直接)

这是Next.js App Router原生支持的临时数据传递方式,数据不会出现在URL中,仅存在于会话内存中(页面刷新后会丢失)。

Page1 跳转代码

import { useRouter } from 'next/navigation';

// ...
const router = useRouter();

router.push(
  `/restaurant/${params.uniqueValue}/checkout/order/${newOrder.data.orderNumber}`,
  {
    state: { 
      test: "test",
      orderData: newOrder.data // 直接传递对象
    }
  }
);

Page2 读取数据代码

import { useRouter } from 'next/navigation';

const router = useRouter();
const routeState = router.state;

console.log(routeState?.test); // 输出 "test"
console.log(routeState?.orderData); // 输出你的订单对象

方案2:React Context 全局状态共享

适合需要在多个页面、组件间共享数据的场景,数据会在页面刷新后保留(取决于你是否做持久化)。

1. 创建Context文件

// app/context/OrderContext.js
'use client';

import { createContext, useContext, useState } from 'react';

const OrderContext = createContext();

export function OrderProvider({ children }) {
  const [orderData, setOrderData] = useState(null);

  return (
    <OrderContext.Provider value={{ orderData, setOrderData }}>
      {children}
    </OrderContext.Provider>
  );
}

export function useOrderContext() {
  return useContext(OrderContext);
}

2. 在根Layout中包裹Provider

// app/layout.js
import { OrderProvider } from './context/OrderContext';

export default function RootLayout({ children }) {
  return (
    <html lang="zh-CN">
      <body>
        <OrderProvider>{children}</OrderProvider>
      </body>
    </html>
  );
}

3. Page1 设置数据并跳转

import { useOrderContext } from '../context/OrderContext';
import { useRouter } from 'next/navigation';

const Page1 = () => {
  const { setOrderData } = useOrderContext();
  const router = useRouter();

  const handleNavigate = () => {
    setOrderData({ test: "test", orderNumber: newOrder.data.orderNumber });
    router.push(`/restaurant/${params.uniqueValue}/checkout/order/${newOrder.data.orderNumber}`);
  };

  return <button onClick={handleNavigate}>跳转到结算页</button>;
};

4. Page2 读取数据

import { useOrderContext } from '../context/OrderContext';

const Page2 = () => {
  const { orderData } = useOrderContext();

  console.log(orderData?.test); // 输出 "test"

  return <div>订单号:{orderData?.orderNumber}</div>;
};

方案3:LocalStorage/SessionStorage 本地存储

适合需要持久化数据,或跨会话传递的场景(注意:敏感数据不要存在本地,有安全风险)。

Page1 存储数据并跳转

import { useRouter } from 'next/navigation';

const router = useRouter();

const handleNavigate = () => {
  // 将对象转为JSON字符串存储
  localStorage.setItem('orderData', JSON.stringify({ 
    test: "test", 
    orderNumber: newOrder.data.orderNumber 
  }));
  router.push(`/restaurant/${params.uniqueValue}/checkout/order/${newOrder.data.orderNumber}`);
};

Page2 读取数据

'use client';

import { useEffect, useState } from 'react';

const Page2 = () => {
  const [orderData, setOrderData] = useState(null);

  useEffect(() => {
    const storedData = localStorage.getItem('orderData');
    if (storedData) {
      setOrderData(JSON.parse(storedData));
      // 读取后建议删除,避免数据残留
      localStorage.removeItem('orderData');
    }
  }, []);

  console.log(orderData?.test);

  return <div>订单号:{orderData?.orderNumber}</div>;
};

各方案适用场景

  • 路由State:临时跳转传数据,简单直接,页面刷新后数据丢失。
  • React Context:多页面/组件共享全局状态,数据持久化可控。
  • LocalStorage:跨会话传递数据,适合非敏感信息的持久化存储。

内容的提问来源于stack exchange,提问作者Poumon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 14:58:18