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

服务端组件间共享数据:避免重复调用getPosts优化咨询

可行,以下是几种实现方案

方案一:将posts作为props传递

把数据获取逻辑统一放在父组件,再将posts传递给不同的布局组件,这样只会调用一次getPosts()。

修改后的代码示例:

import { getPosts } from "../../sanity-utils"

// 布局组件改为接收posts props
function ServerLayout({ posts }) {
  return (
      <div className="">
      {posts.map((post) => (
        <div key={post.id } className="">
          <h1>{post.title}</h1>
          <img src={post.image} alt="image"  className="w-1/3 "/>
        </div>
      ))}
      </div>
  );
}

function CardLayout({ posts }) {
  return (
      <div className="">
      {posts.map((post) => (
        <div key={post.id } className="flex">
          <h1>{post.title}</h1>
          <img src={post.image} alt="image"  className="w-1/3 "/>
        </div>
      ))}
      </div>
  );
}

// 父组件统一获取数据并传递给子组件
export default async function Page() {
  const posts = await getPosts();

  return (
    <div>
      <ServerLayout posts={posts} />
      <CardLayout posts={posts} />
    </div>
  );
}

方案二:缓存getPosts()的结果

如果不想通过props传递数据,可以给getPosts()添加缓存逻辑,这样即使多次调用该方法,也只会实际发起一次请求。

修改sanity-utils中的getPosts:

// sanity-utils.js
let cachedPosts = null;

export async function getPosts() {
  // 如果已有缓存,直接返回
  if (cachedPosts) {
    return cachedPosts;
  }
  // 原数据请求逻辑,这里假设是调用Sanity API
  const response = await fetch('你的Sanity API地址');
  cachedPosts = await response.json();
  return cachedPosts;
}

之后不管Server或Card组件如何调用getPosts(),第一次请求后都会复用缓存数据,不会重复发起请求。

方案三:使用React Context(适合组件层级较深的场景)

如果组件层级复杂,props传递太繁琐,可以用Context来全局共享posts数据。

import { createContext, useContext } from 'react';
import { getPosts } from "../../sanity-utils"

const PostsContext = createContext(null);

// 提供数据的Provider组件
async function PostsProvider({ children }) {
  const posts = await getPosts();
  return (
    <PostsContext.Provider value={posts}>
      {children}
    </PostsContext.Provider>
  );
}

// 自定义Hook用于获取Context中的posts
function usePosts() {
  const posts = useContext(PostsContext);
  if (!posts) throw new Error('usePosts必须在PostsProvider组件内部使用');
  return posts;
}

// 布局组件通过usePosts获取数据
function ServerLayout() {
  const posts = usePosts();
  return (
      <div className="">
      {posts.map((post) => (
        <div key={post.id } className="">
          <h1>{post.title}</h1>
          <img src={post.image} alt="image"  className="w-1/3 "/>
        </div>
      ))}
      </div>
  );
}

function CardLayout() {
  const posts = usePosts();
  return (
      <div className="">
      {posts.map((post) => (
        <div key={post.id } className="flex">
          <h1>{post.title}</h1>
          <img src={post.image} alt="image"  className="w-1/3 "/>
        </div>
      ))}
      </div>
  );
}

// 父组件用PostsProvider包裹所有需要用到数据的组件
export default async function Page() {
  return (
    <PostsProvider>
      <ServerLayout />
      <CardLayout />
    </PostsProvider>
  );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 13:55:08