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

Next.js 13 App Router中,router.push跳转后如何复用前页数据?

几种优化Next.js 13 App Router中测验结果传递的方案

1. 通过router.push传递查询参数(适合小体量非敏感数据)

如果结果数据量不大且不涉及敏感信息,可以直接在跳转时把数据附在URL的查询参数里,避免二次请求数据库。

在/quiz页面提交后:

import { useRouter } from 'next/navigation';

const QuizPage = () => {
  const router = useRouter();

  const handleSubmit = async () => {
    // 提交结果到数据库,拿到返回的结果数据或ID
    const result = await saveResultToDB(quizAnswers);
    
    // 直接传递结果数据(数据量小时适用)
    router.push(`/results?score=${result.score}&total=${result.total}`);
    // 或者传递结果ID(后续用ID做精准查询,比全量查询高效)
    // router.push(`/results?resultId=${result.id}`);
  };
};

在/results页面获取参数:

import { useSearchParams } from 'next/navigation';

const ResultsPage = () => {
  const searchParams = useSearchParams();
  const score = searchParams.get('score');
  const total = searchParams.get('total');

  return (
    <div>
      <p>你的得分:{score}/{total}</p>
    </div>
  );
};

注意:敏感数据不要用这种方式,URL会暴露内容。

2. 使用React Context共享状态

在App Router的根layout中提供全局Context,临时存储测验结果,跳转后/results页面直接读取即可。

首先创建Context:

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

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

const ResultContext = createContext();

export const ResultProvider = ({ children }) => {
  const [quizResult, setQuizResult] = useState(null);

  return (
    <ResultContext.Provider value={{ quizResult, setQuizResult }}>
      {children}
    </ResultContext.Provider>
  );
};

export const useResultContext = () => useContext(ResultContext);

在根layout中引入Provider:

// app/layout.js
import { ResultProvider } from './context/ResultContext';

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

在/quiz页面存储结果:

'use client';

import { useRouter } from 'next/navigation';
import { useResultContext } from '../context/ResultContext';

const QuizPage = () => {
  const router = useRouter();
  const { setQuizResult } = useResultContext();

  const handleSubmit = async () => {
    const result = await saveResultToDB(quizAnswers);
    // 把结果存入Context
    setQuizResult(result);
    router.push('/results');
  };
};

在/results页面读取结果:

'use client';

import { useResultContext } from '../context/ResultContext';

const ResultsPage = () => {
  const { quizResult } = useResultContext();

  if (!quizResult) {
    return <div>加载中...</div>;
  }

  return (
    <div>
      <h2>测验结果</h2>
      <p>得分:{quizResult.score}/{quizResult.total}</p>
      {/* 展示其他结果内容 */}
    </div>
  );
};

3. 利用TanStack Query的缓存机制

如果已经在用TanStack Query(React Query),可以在提交结果的mutation完成后缓存数据,/results页面直接读取缓存,无需额外请求。

在/quiz页面提交并缓存:

'use client';

import { useMutation, useQueryClient } from '@tanstack/react-query';
import { useRouter } from 'next/navigation';

const QuizPage = () => {
  const router = useRouter();
  const queryClient = useQueryClient();

  const saveResultMutation = useMutation({
    mutationFn: saveResultToDB,
    onSuccess: (result) => {
      // 把结果缓存起来,指定唯一key
      queryClient.setQueryData(['quiz-result'], result);
      router.push('/results');
    },
  });

  const handleSubmit = () => {
    saveResultMutation.mutate(quizAnswers);
  };
};

在/results页面读取缓存:

'use client';

import { useQuery } from '@tanstack/react-query';

const ResultsPage = () => {
  // 读取缓存的数据,无需发送实际请求
  const { data: quizResult } = useQuery({
    queryKey: ['quiz-result'],
    queryFn: () => null,
    initialData: () => queryClient.getQueryData(['quiz-result']),
  });

  if (!quizResult) {
    return <div>请先完成测验</div>;
  }

  return (
    <div>
      <h2>测验结果</h2>
      <p>得分:{quizResult.score}/{quizResult.total}</p>
    </div>
  );
};

4. 使用localStorage临时存储(非敏感数据)

如果数据不敏感,提交后把结果存在localStorage,跳转后读取,用完再清除。

在/quiz页面:

'use client';

import { useRouter } from 'next/navigation';

const QuizPage = () => {
  const router = useRouter();

  const handleSubmit = async () => {
    const result = await saveResultToDB(quizAnswers);
    localStorage.setItem('quiz-result', JSON.stringify(result));
    router.push('/results');
  };
};

在/results页面:

'use client';

import { useEffect, useState } from 'react';

const ResultsPage = () => {
  const [quizResult, setQuizResult] = useState(null);

  useEffect(() => {
    const storedResult = localStorage.getItem('quiz-result');
    if (storedResult) {
      setQuizResult(JSON.parse(storedResult));
      // 读取后清除,避免下次进入页面残留数据
      localStorage.removeItem('quiz-result');
    }
  }, []);

  if (!quizResult) {
    return <div>加载中...</div>;
  }

  return (
    <div>
      <h2>测验结果</h2>
      <p>得分:{quizResult.score}/{quizResult.total}</p>
    </div>
  );
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 04:20:30