使用 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 检索服务器端数据并保存在上下文中 的相关文章

  • 在 iPad 上调试 Javascript

    我想知道人们是否找到了任何有用的工具来在未越狱的 iPad 上调试 javascript 这是一款用于工作的 iPad 因此无法越狱 通过一些繁琐的步骤 我已经在 iPad 上运行了 firebug lite 但是我的 javascript
  • 使用 Gmail 上下文小工具访问附件

    我想将电子邮件及其附件从 Gmail Google Apps 保存到另一个数据库以实现类似 CRM 的功能 然而 根据docs http code google com apis gmail gadgets contextual 提取器无法
  • 检测对给定 JavaScript 事件的支持?

    我有兴趣使用 JavaScript hashchange 事件来监视 URL 片段标识符的更改 我知道非常简单的历史 http code google com p reallysimplehistory 以及用于此目的的 jQuery 插件
  • 如何在单页应用程序中使用 #-URL?

    本文 http danwebb net 2011 5 28 it is about the hashbangs提出了一个非常令人信服的论点 因为 URL 是长期存在的 它们被添加书签并传递 所以它们应该是有意义的 并且使用哈希进行真正的路由
  • mocha.opts 已弃用,如何迁移到 package.json?

    我正在开发一个大型项目 自从上周我更新了摩卡以来 现在我们收到警告 DeprecationWarning 通过 mocha opts 进行的配置已被弃用并且 将从 Mocha 的未来版本中删除 使用 RC 文件或 改为 package js
  • ES6 类文字中的 IIFE

    在 ES5 中我们都可以这样做 myClass prototype myMethod function return function 我可以对 ES6 类文字执行同样的操作吗 不 至少现在还没有 ES6 类仅支持声明方法 因此任何不直接为
  • 有没有办法将 Google 文档分割成多个 PDF?

    我想在 Google Scripts VBA 代码中复制我为 Word 文档编写的代码 基本上 它通过搜索我插入文档中的标签 将文档 切片 为多个 PDF 文件 目的是允许合唱团使用 forScore 管理乐谱的应用程序 在切片点插入先前注
  • Javascript 制作音频 blob

    我正在测试 html 音频标签 我想制作音频 blob url 就像 youtube 或 vimeo 那样 并将其添加到 src 开始播放音频 我一直在测试new Blob and URL createObjectURL 但我不知道如何使用
  • 如何将查询参数添加到守卫中的路由并将其传递给 Angular 4 中的组件?

    我在我的 Angular 4 应用程序中使用路由保护 如果条件满足并返回 true 我想向路由添加一个查询参数 这是我一直在研究的代码 Injectable export class ViewGuardService implements
  • “move(-1)”作为 AngularJS 表达式有什么问题吗?

    我收到此错误 parse ueoe Unexpected end of expression move 从这段代码来看
  • Lightbox:如何翻译“Image x of x”文本?

    我使用 Lightbox 2 作为图像集 当我的网站的访问者单击该集中的缩略图时 它将显示 图像的放大版本 下面是 描述 取自 a 标题属性 其下方 文本 Image x of x 例如 Image 1 of 12 有谁知道在哪里翻译 更改
  • 将屏幕宽度获取到 javascript 变量中并通过 ajax 将其发送到 php 页面以避免页面加载

    这是JS检测我的页面命名上的屏幕分辨率index html并将其发送到 php 以便可以使用以下方式检索值 GET 这是我的PHP文件命名的内容process php
  • Flask 和 Reactjs 抛出 JSX 转换错误

    我已经开始将 ReactJS 与 Python Flask 后端结合使用 通过 Flask 渲染模板时 我在 Chrome 控制台中收到以下客户端错误 错误 找不到模块 jstransform visitors es6 templates
  • 在 Windows 上静默安装 Qt55 Enterprise

    编辑 在 Qt 支持的帮助下 我已经解决了如何自动化 Qt 企业安装程序的这两个部分 下面是脚本调用 我正在尝试在 Windows 8 1 和 Windows 10 上静默安装 Qt 5 5 1 Enterprise 使用 script 开
  • jQuery 模板插件:如何创建双向绑定?

    我开始使用 jQuery 模板插件 微软创建的 但现在我面临这个问题 模板用于绑定到对象数组的一堆表单 当我更改其中一个表单上的某些内容时 我希望更新绑定的对象 但我不知道如何自动执行该操作 这是一个简单的例子 现实生活中的模板和对象要复杂
  • 为什么我从 c# 到 js 得到不同的 MD5 哈希值?

    我有一个用于加密密码的 C 函数 System Security Cryptography MD5CryptoServiceProvider md5Provider new System Security Cryptography MD5C
  • redux - 如何存储和更新键/值对

    我正在使用 redux 和 React js 我想存储简单的键 值对 但无法获得正确的减速器语法 在这种情况下 每个键 值对将保持与外部系统的连接 这是正确的做法吗 我刚开始使用 redux 所以这有点神秘 export default s
  • 如何在react.js中将/n替换为换行符?

    我正在尝试更换每一个 n to a br tag in ReactJS In my note note对象有一个包含多个的字符串 n in it 示例注释 注释 test ntest ntest 我尝试过的ReactJS note note
  • 引导网格中的绘图图周围有巨大的空白

    我有一个 Net 应用程序 我试图在其中使用创建一个图表bootstrap js and plotly js 当我创建响应式图表时 我遇到网格中存在巨大空白的问题 我发现问题的一部分是plotly svg container的大小默认高度为
  • 文件和目录条目 API 在 Chrome 中损坏?

    我正在尝试使用文件和目录条目 API 创建一个文件上传器工具 该工具允许我将文件和目录的任意组合放入浏览器窗口中 以供读取和上传 我完全意识到 可以通过使用文件输入元素来实现类似的功能webkitdirectory已启用 但我正在测试一个用

随机推荐

  • 在 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 这允