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

Next.js 13中revalidate仅刷新服务端组件,客户端组件Props不更新求助

问题描述

我有一组数据,通过两种方式展示:一是在服务端组件中直接显示,二是将数据作为Props传递给客户端组件ManageTable进行渲染。当数据发生变化后,我调用revalidatePath或router.refresh()方法,仅服务端组件显示的数据更新为正确值,但客户端组件的Props未更新,组件也未重新渲染。我期望服务端组件和客户端组件中的fund!.partners数据保持一致。

代码示例

import React from "react";
import AddForm from "./AddForm";
import { Fund, PartnerData, fundCollection } from "@/lib/mongodb";
import ManageTable from "./table";
import { revalidatePath } from "next/cache";
import { WithId } from "mongodb";

export default async function Manage() {
  var funds;
  var fund: WithId<Fund>;
  try {
    console.log("refetchign");
    funds = await (await fundCollection).find({ name: "fund_name" }).toArray();
    fund = funds[0];
    console.log(fund.partners);
  } catch (e) {
    console.log("ERROR", e);
  }

  return (
    <div>
      {/* On revalidatePath or router.refresh(), this updates to correct value */}
      {JSON.stringify(fund!.partners)}
      {/* This is a client component. Data passed as props. This does not update to the correct value */}
      <ManageTable rows={fund!.partners} />
    </div>
  );
}
解决方案

问题原因

Next.js中,客户端组件会缓存初始接收的props,调用revalidatePath或router.refresh()时,服务端组件会重新拉取数据并渲染,但客户端组件若无合适的缓存策略或状态同步机制,不会自动更新props。

解决方法

  • 给客户端组件绑定动态key
    为ManageTable添加与数据内容关联的key,数据变化时key改变会触发组件重新挂载,从而获取新props:

    <ManageTable 
      rows={fund!.partners} 
      key={JSON.stringify(fund!.partners)} 
    />
    

    注:若数据量较大,JSON.stringify可能影响性能,建议用数据中的唯一标识字段拼接生成key。

  • 在客户端组件内部监听props变化
    在ManageTable中用useEffect监听rows props,同步更新内部状态触发渲染:

    // ManageTable.tsx(客户端组件)
    "use client";
    import { useEffect, useState } from "react";
    
    export default function ManageTable({ rows }) {
      const [localRows, setLocalRows] = useState(rows);
    
      useEffect(() => {
        setLocalRows(rows);
      }, [rows]);
    
      // 使用localRows渲染表格
      return <table>{/* 表格渲染逻辑 */}</table>;
    }
    
  • 调整数据获取的缓存策略
    确保服务端数据获取逻辑未被过度缓存,可通过unstable_cache设置缓存规则:

    import { unstable_cache } from "next/cache";
    
    const getFunds = unstable_cache(
      async () => (await fundCollection).find({ name: "fund_name" }).toArray(),
      ["fund_data"],
      { revalidate: 0 } // 禁用缓存,每次请求重新获取
    );
    
    // 在组件中调用
    funds = await getFunds();
    

内容的提问来源于Stack Exchange,提问作者Max K

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 17:57:29