使用 Next.js 检索服务器端数据并保存在上下文中

2024-01-02

我希望能够从服务器端 API 检索数据,并将其加载到 React 上下文中,以便使其可供我的应用程序中的任何组件使用。我尝试过各种事情,但似乎没有什么能让我完全做我想做的事。我尝试过的一些事情包括:

getServerSideProps - 这允许我检索服务器端的数据,但仅适用于页面组件,因此如果我希望每个页面上都可用此数据,并且我不知道我的用户将登陆哪个页面,我需要将此逻辑添加到每个页面。

_app.js 中的 getInitialProps - 我可以将其添加到 _app.js 组件中,该组件将在服务器端运行,并可以通过上下文提供程序使其可供所有组件使用,但问题是它在每个页面上运行,甚至导航客户端时。我希望能够调用 API 一次且仅一次,但这似乎不允许。

_document.js 中的 getInitialProps - 我可以将其添加到 _document.js 组件中,该组件仅在服务器上运行,这似乎解决了每个页面都调用它的问题,但我不知道如何将其存储在 React 上下文中从那里。事实上,我似乎不知道如何在任何地方访问这些数据。看起来 _document.js 中的 getInitialProps 被调用aftergetInitialProps 在 _app.js 中,所以我不确定当我在 _app.js 中时是否可以使用从 _document.js 中的 getInitialProps 生成的值。

如果我在客户端上调用 API,可以通过多种方法实现此目的,但这不适用于我的用例,因为当客户端使用 API 中的数据进行更新时,它会导致内容闪烁。

有人想出解决这个用例的方法吗?


Next.js 13+ 答案

Next.js 实验性应用程序文件夹现在完美地涵盖了这个用例。

通过 React 上下文将值从 RSC 传递到客户端组件

  1. 在 React Server Component (RSC) 布局中获取数据
  2. 在此布局中,使用此值渲染 React 上下文
  3. 根据需要在您的应用程序中使用此上下文

当然,您可以在树中更下方的 RSC 中设置此上下文,例如,如果您仅在某个页面或页面的某个组件上需要它。

在这个现实生活中的例子中 https://github.com/Devographics/Monorepo/blob/f5c63d45e9e0367c94ab73966b34a1474098085b/surveyform/src/app/%5Blang%5D/survey/%5Bslug%5D/%5Byear%5D/layout.tsx#L111,我在 RSC 页面中获取调查定义,并通过上下文将其传递给客户端代码。我的上下文提供者 https://github.com/Devographics/Monorepo/blob/f5c63d45e9e0367c94ab73966b34a1474098085b/surveyform/src/surveys/components/SurveyContext/Provider.tsx暴露一个类型化的可重用钩子。

React 服务器组件的示例代码(此处为页面):

// /app/referer/page.tsx (Server Component)
import { headers } from 'next/headers'
export default async function Page() {
  const headersList = headers()
  const referer = headersList.get('referer')
  return (
    // we set a CLIENT context,
    // based on the SERVER context that we got via headers()
    <RefererProvider value={referer}>
      <InteractiveReferer />
    </RefererProvider>
  )
}

客户端上下文的示例代码(别忘了"use client"指示):

// /components/InteractiveReferer.tsx (Client Component)
// use "client"
export const InteractiveReferer = () => {
  // this context has been initialized by a parent RSC
  // but we can access it as expected in a Client Component
  const referer = useRefererContext()
  const [clickedReferer, setClickedReferer] = useState(false)
  return (
    <button
      onCLick={() => {
        setClickedReferer(true)
      }}
    >
      Referer: {referer}
    </button>
  )
}

通过缓存将值从 RSC 传递到其他 RSC

Next.js 应用程序文件夹的另一个新颖之处是,现在服务器端代码不再局限于页面级别getServerSideProps不再了。嵌套组件也可以是服务器组件并触发服务器调用。因此,有时您可能不仅想设置客户端上下文,还想设置一种服务器端上下文,其范围仅限于当前请求。

I 广泛描述这个用例 https://prismic.io/blog/advanced-nextjs-server-context在本文中。综上所述,可以使用React 18cache函数(在撰写本文时尚未记录)来实现此目标。

我精心制作了该模式的开源演示 https://github.com/eric-burel/next13-server-context/blob/fd4bd2633aeb9b6c3412d9fb8e829e48de6a5d2a/src/app/getServerContext.ts,可以通过以下代码示例进行总结:

import { cache } from "react";

export const getServerContext = cache(() => ({
    // a dummy context for the demonstration
    createdAt: Date.now().toString(),
    calledByLayout: false,
    calledByPage: false,
    calledByNested: false
}))

您可以直接改变返回值以在此上下文中存储新信息。

命名注意事项:我一直使用术语“服务器上下文”来指定存储在cache充当上下文。这是因为它是“客户端”上下文的服务器端等效项。 然而,“请求缓存”可能更合适,因为“服务器上下文”在 Next.js 和 React 的未来版本中可能用于其他目的(在 RSC 和客户端组件之间共享数据)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Next.js 检索服务器端数据并保存在上下文中 的相关文章

  • 我如何能够以两行显示标题,并且每行的字体大小不同?

    我正在使用 Google Chart API 创建时间线图 并希望将图的标题修改为两行 问题 我如何能够显示具有不同字体大小的两线图表标题 电流输出 理想输出 相关研究 我唯一能找到的是有人试图用饼图来做到这一点 但我尝试了但无法使其发挥作
  • 由于 apollo-client 未定义,无法解构 GraphQL 查询?

    我正在寻找调试与错误消息相关的问题 未捕获的类型错误 无法解构 0 apollo client WEBPACK IMPORTED MODULE 4 useQuery 因为它未定义 Context 我正在为我的 React js 项目设置后端
  • 如何使用 JavaScript 创建链接?

    我有一个标题字符串和一个链接字符串 我不知道如何将两者放在一起以使用 JavaScript 在页面上创建链接 任何帮助表示赞赏 我试图解决这个问题的原因是因为我有一个 RSS 源并且有一个标题和 URL 列表 我想将标题链接到 URL 以使
  • Javascript 函数查找数字的倍数

    创建一个名为的函数multiplesOf 它将接受两个参数 第一个参数是数字数组 第二个参数是数字 该函数应返回一个新数组 该数组由参数数组中的每个数字组成 该数字是参数数字的倍数 So multiplesOf 5 6 7 8 9 10 3
  • 在 contenteditable div 中选择范围

    我有一个contenteditablediv 和其中的一些段落 这是我的代码 div style border solid 1px black width 300px height 300px div Hello world div div
  • JavaScript 中的埃拉托斯特尼筛法对大量数据无限运行

    我一直在尝试写埃拉托斯特尼筛法 http en wikipedia org wiki Sieve of EratosthenesJavaScript 中的算法 基本上我只是按照以下步骤操作 创建从 2 到 n 1 的连续整数列表 令第一个素
  • 如何修改每个JSON对象javascript

    我想修改里面的每个 JSON 值cooldown object cooldown user 1 This user2 0 This 在 Javascript 中使用 for 语句 我研究了好几个小时 只找到了内部的 blocks Edit
  • Chrome 中的性能问题

    我目前正在从事一个相对较大的项目 使用 AngularJs 构建 应用程序的一部分是一个表单 您可以向其中添加任意数量的页面 不幸的是 添加了很多不必要的垃圾 即表示表单模型的对象可能会变得非常大 在某些时候 Chrome 基本上无法处理它
  • 图像无法在带有 DOM 的 IE 中加载:控制台中的 7009 错误(无法解码)

    当在 IE 中的单个页面上加载许多图像时 在 IE11 中重现 其中一些图像开始加载失败 并在控制台中出现类似以下警告的内容 DOM7009 无法解码 URL 处的图像 某些唯一的 url 当我查看网络流量时 似乎确实从服务器收到了每个图像
  • 使用 dc.js 按条形值对条形图中的条形进行排序(排序)

    如何通过维度的计算值而不是维度本身的名称对 dc js 示例中的 x 轴 维度 进行排序 例如 请考虑序数条形图的 dc js 示例 https github com dc js dc js blob master web examples
  • React-Redux:state.setIn() 和 state.set() 有什么区别?

    我见过使用setIn and set 在一些react redux代码中 state setIn state set 我在这里找到了一些文档https facebook github io immutable js https facebo
  • 在 HTML5 画布中,如何用我选择的背景遮盖图像?

    我试图用画布来实现这一点 globalCompositeOperation 但没有运气 所以我在这里问 这里有类似的问题 但我没有在其中找到我的案例 我的画布区域中有图层 从下到上的绘制顺序 画布底座填充纯白色 fff 用fillRect
  • Javascript split 不是一个函数

    嘿朋友们 我正在使用 javascript sdk 通过 jQuery facebook 多朋友选择器在用户朋友墙上发布信息 但是我收到此错误friendId split 不是函数 这是我的代码 function recommendToFr
  • Vuejs 2:去抖动不适用于手表选项

    当我在 VueJs 中反跳此函数时 如果我提供毫秒数作为原语 它就可以正常工作 但是 如果我将其提供为对 prop 的引用 它会忽略它 这是道具的缩写版本 props debounce type Number default 500 这是不
  • Firebase 函数 onWrite 未被调用

    我正在尝试使用 Firebase 函数实现一个触发器 该触发器会复制数据库中的一些数据 我想观看所有添加的内容votes user vote 结构为 我尝试的代码是 const functions require firebase func
  • 从数据库检查数据的异步解决方案各种循环子句

    我想要做的是异步检查数据库并从中获取结果 在我的应用程序中我试图实现Asynchronously将此步骤解决为 从数据库中检查手机号码JsonArray循环子句的种类 Create JsonArray从结果 打印创建的数组 我学到了足够多的
  • Vue 和 Vuex:处理依赖的计算属性

    我的应用程序是一个使用 Vuex 在 Vue 中构建的精简电子表格 关键组件是TableCollection Table and Row The TableCollection有一个包含多个的数组Table对象 每个Table有一个包含多个
  • 用于交互式图形绘制的轻量级 JavaScript 库? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我有兴趣了解用于绘制交互式图表的最轻量级 javascript 库 我掌握的数据主要是与海洋研究相关的科学数据 我知道一些 jquery
  • 在 CKEditor 中设置字体大小和字体系列

    我正在使用 ckeditor 我想问一下这个插件如何设置font family和font size 我尝试过使用 CKEDITOR config font defaultLabel Arial CKEDITOR config fontSiz
  • 如何确定所有角度2分量都已渲染?

    当所有 Angular2 组件完成渲染时 是否会触发一个角度事件 For jQuery 我们可以用 function 然而 对于 Angular2 当domready事件被触发 html 只包含角度组件标签 每个组件完成渲染后 domrea

随机推荐

  • 在 adb logcat 输出中查看 Android 上 Qt 应用程序的日志记录的最简单方法是什么?

    NB I am notQtCreator 用户 我使用 qmake make 和 androiddeployqt 在构建脚本中构建 Android 应用程序 并使用 adb install 将它们部署到设备 我希望能够在 abd logca
  • git pre-commit hook,将文件添加到索引中

    我正在尝试编写一个简单的预提交挂钩来检查文件是否被修改 如果是 则压缩它并将其添加到当前索引中 如下所示 bin sh was the file modified mf git status grep jquery detectBrowse
  • 同步 AJAX 调用在 Chrome 中冻结之前的代码

    我想在执行同步 AJAX 调用时将按钮更改为加载状态 除了将按钮更改为加载状态的 jQuery 代码 在 Chrome 中 之外 它会冻结 直到 AJAX 调用完成 因此 加载状态将在 de ajax 调用后显示大约 1 毫秒 我在 JSF
  • OpenGL:快速离屏渲染

    我需要使用 OpenGL 在屏幕外渲染大量 数万 图像 我在Windows下运行并使用QT作为框架 解决方案只能是Windows 这并不重要 根据我使用谷歌的发现 有很多选择可以做到这一点本文 http www mesa3d org bri
  • 如何在python中将输入值与mysql数据库值进行比较

    所以我想将输入值与我的数据库值进行比较 如果输入值与数据库的值相同 我想print inputvalue 但如果不一样 我想print Data Does Not Exist 所以我尝试过这段代码 cur connection cursor
  • 是什么让 DCG 谓词变得昂贵?

    我正在构建一个定语从句语法来解析 20 000 段半自然文本 随着我的谓词数据库大小的增长 现在达到 1 200 条规则 解析字符串可能需要相当长的时间 特别是对于 DCG 目前无法解释的字符串 因为我尚未编码语法 对于包含 30 个单词的
  • 将 scotty 帖子的 do 替换为 >>=

    post introduceAnIdea do command lt jsonData json handle command 如何删除 do 并用 gt gt 更改它 post introduceAnIdea jsonData gt gt
  • 为什么网站的 MVC 需要单点入口?

    我看到许多网站的 MVC 实现都有一个单入口点 例如 index php 文件 然后解析 URL 以确定要运行哪个控制器 这对我来说似乎很奇怪 因为它涉及到必须使用 Apache 重写来重写 URL 并且页面足够多 单个文件会变得臃肿 为什
  • 什么是文件描述符,用简单的术语解释一下?

    与维基百科相比 文件描述符的更简化描述是什么 为什么需要它们 比如说 以shell进程为例 它是如何应用的呢 进程表是否包含多个文件描述符 如果是 为什么 简而言之 当您打开文件时 操作系统会创建一个条目来表示该文件并存储有关该打开文件的信
  • Circleci:pip install dlib 失败

    我有一个 python 项目需要dlib 我正在尝试设置 CircleCI 并编写我的config yml如下 Python CircleCI 2 0 configuration file Check https circleci com
  • NestJS:如何在 canActivate 中模拟 ExecutionContext

    我在模拟 Guard 中间件中的 ExecutionContext 时遇到问题 这是我的 RoleGuard 扩展 JwtGuard Injectable export class RoleGuard extends JwtAuthGuar
  • @Transactional注解

    之间有什么区别 为整个类添加 Transactional 注释 为每个方法添加 Transactional 注释 使用 spring 和 Hibernate 基本上 如果你用 Transactional http static spring
  • 如何“扫描”当前安装的 VCL 组件的完整列表

    我还没有找到真正满意的答案这个问题 https stackoverflow com questions 691989 full vcl class browser for delphi 现在正在考虑推出自己的 我有 ModelMaker 和
  • Entity Framework 4 v2 中与 POCO 的一对一关系

    我一直在寻找有关如何在 EF4v2 中与 POCO 建立一对一关系的示例 我发现很多例子只展示了如何创建一对多或多对多 你有这方面的资源吗 这对我有用 using System using System Collections Generi
  • 国际象棋:高分支因子

    我正在尝试开发一个简单的国际象棋引擎 但我在其性能方面遇到了困难 我已经通过 alpha beta 修剪和迭代加深 没有任何额外的启发式 实现了 Negamax 但是我无法获得超过 3 4 层的合理搜索时间 以下是我的程序从游戏开始时的日志
  • javax 邮件:UTF-8 编码问题

    我已经看到了几个与此相关的问题 但没有一个能解决我的问题 我有一封带有 pdf 附件的中文电子邮件 所有文本在包含在多部分电子邮件中之前都是有效的 UTF 8 Problem 电子邮件中的文本到达收件人时是垃圾字符 电子邮件标头显示其编码不
  • 从 iPhone 中的固定数字集生成随机数

    假设我有一组数字 即 1 6 3 5 7 9 我只想从这组数字生成随机数 即生成的数字应该是随机的 并且应该仅来自这些数字 1 6 3 5 7 9 标准 C C 函数也可以 arc4random set count 随机索引
  • python:如何根据 1 个列表中的内容从 2 个列表中删除值

    我有 2 个号码列表 其中一个名为xVar另一个叫yVar 我将使用这两个元素在图表上绘制 X 和 Y 值 它们都具有相同数量的元素 通常情况下 我只会绘制 ax scatter xVar yVar s 2 color tomato 我想从
  • 访问 symfony 2 中的 AppKernel 环境变量

    我正在使用 symfony 2 我们有 2 个配置 开发版和生产版 我需要知道是否可以找出我在实体或模型中使用的是哪一个 我正在寻找与 AppKernel php 中找到的代码类似的内容 this gt getEnvironment 如果我
  • 使用 Next.js 检索服务器端数据并保存在上下文中

    我希望能够从服务器端 API 检索数据 并将其加载到 React 上下文中 以便使其可供我的应用程序中的任何组件使用 我尝试过各种事情 但似乎没有什么能让我完全做我想做的事 我尝试过的一些事情包括 getServerSideProps 这允