当前位置: 首页 > news >正文

一般网站的宽度是多少建筑装饰设计培训班

一般网站的宽度是多少,建筑装饰设计培训班,建设银行官方网站网页版,珠海cp网站建设数据获取 数据获取、缓存和重新验证 数据获取是任何应用程序的核心部分。本页介绍如何在 React 和 Next.js 中获取、缓存和重新验证数据。 有四种方法可以获取数据#xff1a; 在服务器上#xff0c;使用 fetch在服务器上#xff0c;使用第三方库在客户端上#xff0c;…数据获取 数据获取、缓存和重新验证 数据获取是任何应用程序的核心部分。本页介绍如何在 React 和 Next.js 中获取、缓存和重新验证数据。 有四种方法可以获取数据 在服务器上使用 fetch在服务器上使用第三方库在客户端上通过路由处理程序在客户单上使用第三方库 在服务器上使用 fetch 获取数据 Next.js 扩展了原生的 fetch Web API允许你为服务器上的每个 fetch 请求配置缓存和重新验证行为。React 扩展了 fetch以便在渲染 React 组件树时自动存储 fetch 请求。 在服务器组件、路由处理程序和服务器操作中可以将 fetch 与 async/await 一起使用。 例如 // app/page.tsxasync function getData() {const res await fetch(https://api.example.com/...)// 返回值是 *not* 序列化的// 你可以返回 Date、Map、Set等if (!res.ok) {// 这将激活最接近的 error.js 错误边界throw new Error(Failed to fetch data)}return res.json() }export default async function Page() {const data await getData()return main/main }需要知道 Next.js 提供了在服务器组件如cookies 和 headers中获取数据时可能需要的有用功能。这将导致路由被动态渲染因为它们依赖于请求时间信息在路由处理程序中由于路由处理程序不是 React 组件树的一部分所有 fetch 请求不会被存储要在带有 TypeScript 的服务器组件中使用 async/await你需要使用 TypeScript 5.1.3 或更高版本的 types/react 18.2.8 或更高级别 缓存数据 缓存仓库数据因此不需要在每次请求时都从数据源重新获取数据。 默认情况下Next.js 会自动将 fetch 的返回值缓存在服务器上的数据缓存中。这意味着数据可以在构建时或请求时提取、缓存并在每个数据请求中重用。 // force-cache 是默认值可以省略 fetch(https://..., { cache: force-cache })使用 POST 方法的 fetch 请求也会自动缓存。除非它在使用 POST 方法的路由处理程序中否则它不会被缓存。 什么是数据缓存 数据缓存是一个持久的 HTTP 缓存。根据你的平台缓存可以自动扩展并在多个区域之间共享。 了解有关数据缓存的更多信息。 重新验证数据 重新验证是清除数据缓存并重新回去数据的过程。当你的数据发送更改并且你希望确保显示最新信息时这一点非常有用。 缓存数据可以通过两种方式重新验证 基于时间的重新验证在经过一定时间后自动重新验证数据。这对于很少更改且新鲜度不那么重要的数据非常有用。按需重新验证根据事件手动重新验证数据例如表单提交。按需重新验证可以使用基于标记或基于路径的方法一次重新验证数据组。当你希望确保尽快显示最新数据时例如当无头 CMS 的内容更新时这一点非常有用。 基于时间的重新验证 要按一定时间间隔重新验证数据可以使用 fetch 的 next.revalidate 选项设置资源的缓存生存期以秒为单位。 fetch(https://..., { next: { revalidate: 3600 } })或者要重新验证路由段中的所有 fetch 请求可以使用段配置选项。 // layout.js | page.jsexport const revalidate 3600 // 最多每小时重新验证一次如果在静态渲染的路由中有多个 fetch 请求并且每个请求都有不同的重新验证频率。最低时间将用于所有请求。对于动态渲染的路由每个 fetch 请求都将独立地重新验证。 了解有关基于时间的重新验证的更多信息。 按需重新验证 可以按需通过服务器操作或路由处理程序中的路由revalidatePath或缓存标记revalidateTag重新验证数据。 Next.js 有一个缓存标记系统用于使跨路由的 fetch 请求无效。 使用 fetch 时可以选择使用一个或多个标记标记缓存条目然后你可以调用 revalidateTag 来重新验证与标记相关联的所有条目 例如以下 fetch 请求会添加缓存标记 collection // app/page.tsxexport default async function Page() {const res await fetch(https://..., { next: { tags: [collection] } })const data await res.json()// ... }然后你可以通过在服务器操作中调用 revalidateTag 来重新验证此带有 collection 标记的 fetch 调用 // app/actions.tsuse serverimport { revalidateTag } from next/cacheexport default async function action() {revalidateTag(collection) }了解更多按需重新验证。 错误处理和重新验证 如果在尝试重新验证数据时抛出错误则将继续从缓存中提供最后一个成功生成的数据。在下一个后续请求中Next.js 将重试重新验证数据。 选择退出数据缓存 如果出现以下情况则不会缓存 fetch 请求 cache: no-store 被添加到 fetch 请求中revalidate: 0 选项被添加到各个 fetch 请求中fetch 请求位于使用 POST 方法的路由器处理程序中fetch 请求是在使用 headers 或 cookies 之后发出的使用了 const dynamic force-dynamic 路由段选项fetchCache 路由段选项默认配置为跳过缓存fetch 请求使用 Authorization 或 Cookie 头并且在组件树中有一个未缓存的请求 单个 fetch 请求 要选择不缓存单个 fetch 请求可以将 fetch 中的 cache 选项设置为 no-store。这将在每次请求时动态获取数据。 // layout.js | page.jsfetch(https://..., { cache: no-store })查看 fetch API 引用中的所有可用缓存选项。 多个 fetch 请求 如果在一个路由段例如布局或页面中有多个 fetch 请求则可以使用段配置选项配置该段中所有数据请求的缓存行为。 但是我们建议单独配置每个 fetch 请求的缓存行为。这使你能够对缓存行为进行更精细的控制。 使用第三方库在服务器上获取数据 如果你使用的第三方库不支持或不公开 fetch例如数据库、CMS 或 ORM 客户端则可以使用路由段配置选项和 React 的 cache 功能配置这些请求的缓存和重新验证行为。 是否缓存数据将取决于路由段是静态渲染还是动态渲染。如果段是静态的默认则请求的输出将被缓存并作为路由段的一部分重新验证。如果分段是动态的则不会缓存请求的输出并且在渲染分段时会在每个请求上重新获取该输出。 你还可以使用实验性的 unstable_cache API。 例子 在以下示例中 React cache 函数用于存储数据请求。 在 layout.ts 和 page.ts 段中revalidate 选项设置为 3600这意味着数据将被缓存并最多每小时重新验证一次。 // app/utils.tsimport { cache } from reactexport const getItem cache(async (id: string) {const item await db.item.findUnique({ id })return item })尽管 getItem 函数被调用了两次但只会对数据库进行一次查询。 // app/item/[id]/layout.tsximport { getItem } from /utils/get-itemexport const revalidate 3600 // 最多每小时重新验证一次数据export default async function Layout({params: { id }, }: {params: { id: string } }) {const item await getItem(id)// ... }// app/item/[id]/page.tsximport { getItem } from /utils/get-itemexport const revalidate 3600 // 最多每小时重新验证一次数据export default async function Page({params: { id }, }: {params: { id: string } }) {const item await getItem(id)// ... }使用路由处理程序在客户端上获取数据 如果需要在客户端组件中获取数据可以从客户端调用路由处理程序。路由处理程序在服务器上执行并将数据返回给客户端。当您不想向客户端公开敏感信息如API 令牌时这很有用。 有关示例请参阅路由处理程序文档。 服务器组件和路由处理程序 由于服务器组件在服务器上渲染因此不需要从服务器组件调用路由处理程序来获取数据。相反您可以直接在服务器组件内部获取数据。 使用第三方库在客户端上获取数据 您还可以使用第三方库如SWR 或 React Query在客户端上获取数据。这些库提供了自己的 API用于存储请求、缓存、重新验证和更改数据。 未来的 API use 是一个 React 函数它接受并处理函数返回的 promise。目前不建议在客户端组件中使用在 use 中嵌套 fetch并且可能会触发多次重新渲染。在 React 文档中了解更多有关 use。 服务器操作和突变 服务器操作是在服务器上执行的异步函数。它们可以在服务器和客户端组件中用于处理 Next.js 应用程序中的表单提交和数据突变。 通过服务器操作了解有关形式和突变的更多信息→ YouTube10分钟 约定 服务器操作可以用 React use server 定义指令。你可以将该指令放在 async 函数的顶部以将该函数标记为服务器操作也可以放在单独文件的顶部将该文件的所有导出标记为服务器动作。 服务器组件 服务器组件可以使用内联功能级别或模块级别的 use server 指令。要内联服务器操作请在函数体顶部添加 use server // app/page.tsx// 服务器组件 export default function Page() {// 服务器操作async function create() {use server// ...}return (// ...) }客户端组件 客户端组件只能导入使用模块级 use server 指令的操作。 要在客户端组件中调用服务器操作请创建一个新文件并在其顶部添加 use Server 指令。文件中的所有函数都将标记为可在客户端组件和服务器组件中重复使用的服务器操作 // app/actions.tsuse serverexport async function create() {// ... }// app/ui/button.tsximport { create } from /app/actionsexport function Button() {return (// ...) }你还可以将服务器操作作为 prop 传递给客户端组件 ClientComponent updateItem{updateItem} /// app/client-component.jsxuse clientexport default function ClientComponent({ updateItem }) {return form action{updateItem}{/* ... */}/form }行为 可以使用 form 元素中的 action 属性调用服务器操作 默认情况下服务器组件支持渐进式增强这意味着即使 JavaScript 尚未加载或被禁用表单也会被提交。在客户端组件中如果 JavaScript 尚未加载调用服务器操作的表单将对提交进行排队从而优先考虑客户端水合。水合后浏览器不会在表单提交时刷新。 服务器操作不限于 form可以从事件处理程序、useEffect、第三方库和其他表单元素如button调用。服务器操作与 Next.js 缓存和重新验证体系结构集成。当调用一个操作时Next.js 可以在单个服务器往返中返回更新的 UI 和新数据。在幕后操作使用 POST 方法并且只有此 HTTP 方法才能调用它们。服务器操作的参数和返回值必须可由 React 序列化。有关可序列化参数和值的列表请参阅 React 文档。服务器操作是函数。这意味着它们可以在应用程序中的任何位置重复使用。服务器操作从其使用的页面或布局继承运行时。 例子 表单 React 扩展了 HTML form 元素允许使用 action prop 调用服务器操作。 在表单中调用时该操作会自动接收 FormData 对象。你不需要使用 React useState 来管理字段而是可以使用本地 FormData 方法提取数据 // app/invoices/page.tsxexport default function Page() {async function createInvoice(formData: FormData) {use serverconst rawFormData {customerId: formData.get(customerId),amount: formData.get(amount),status: formData.get(status),}// 变异数据// 重新验证缓存}return form action{createInvoice}.../form }需要知道 示例带有加载和错误状态的表单 在处理具有多个字段的表单时你可能需要考虑将 entries() 方法与 JavaScript 的 Object.fromEntries() 一起使用。例如const rawFormData Object.fromEntries(formData.entries()) 请参阅 React form 文档以了解更多信息。 传递其他参数 你可以使用 JavaScript bind 方法将其他参数传递给服务器操作。 // app/client-component.tsxuse clientimport { updateUser } from ./actionsexport function UserProfile({ userId }: { userId: string }) {const updateUserWithId updateUser.bind(null, userId)return (form action{updateUserWithId}input typetext namename /button typesubmitUpdate User Name/button/form) }除了表单数据外服务器操作还将接收 userId 参数 // app/actions.jsuse serverexport async function updateUser(userId, formData) {// ... }需要知道 另一种选择是将参数作为表单中的隐藏输入字段传递例如input type“hidden” name“userId” value{userId} /。但是该值将是渲染的 HTML 的一部分不会进行编码。 .bind 适用于服务器组件和客户端组件。它还支持渐进增强。 挂起的状态 你可以使用 React useFormStatus hook 来显示提交表单时的挂起状态。 useFormStatus 返回特定 form 的状态因此必须将其定义为 form 元素的子级。useFormStatus 是一个 React hook因此必须在客户端组件中使用。 // app/submit-button.tsxuse clientimport { useFormStatus } from react-domexport function SubmitButton() {const { pending } useFormStatus()return (button typesubmit aria-disabled{pending}Add/button) }SubmitButton / 然后可以以任何形式嵌套 // app/page.tsximport { SubmitButton } from /app/submit-button import { createItem } from /app/actions// 服务器组件 export default async function Home() {return (form action{createItem}input typetext namefield-name /SubmitButton //form) }服务器端验证和错误处理 我们建议使用 HTML 验证如 required 和 typeemail 进行基本的客户端表单验证。 对于更高级的服务器端验证可以使用类似 zod 的库要在更改数据之前验证表单字段请执行以下操作 // app/actions.tsuse serverimport { z } from zodconst schema z.object({email: z.string({invalid_type_error: Invalid Email,}), })export default async function createUser(formData: FormData) {const validatedFields schema.safeParse({email: formData.get(email),})// 如果表单数据无效请提前返回if (!validatedFields.success) {return {errors: validatedFields.error.flatten().fieldErrors,}}// 突变数据 }一旦在服务器上验证了字段就可以在操作中返回一个可序列化的对象并使用 React useFormState hook 向用户显示消息。 通过将操作传递给 useFormState操作的函数签名将更改为接收新的 prevState 或 initialState 参数作为其第一个参数。 useFormState 是一个 React 钩子因此必须在客户端组件中使用。 // app/actions.tsuse serverexport async function createUser(prevState: any, formData: FormData) {// ...return {message: Please enter a valid email,} }然后你可以将操作传递到 useFormState hook并使用返回的 state 显示错误消息。 // app/ui/signup.tsxuse clientimport { useFormState } from react-dom import { createUser } from /app/actionsconst initialState {message: null, }export function Signup() {const [state, formAction] useFormState(createUser, initialState)return (form action{formAction}label htmlForemailEmail/labelinput typetext idemail nameemail required /{/* ... */}p aria-livepolite classNamesr-only{state?.message}/pbuttonSign up/button/form) }需要知道 在更改数据之前应始终确保用户也有权执行操作。请参阅身份验证和授权。 乐观地更新 你可以使用 React useOptimistic hook以便在服务器操作完成之前乐观地更新 UI而不是等待响应 // app/page.tsxuse clientimport { useOptimistic } from react import { send } from ./actionstype Message {message: string }export function Thread({ messages }: { messages: Message[] }) {const [optimisticMessages, addOptimisticMessage] useOptimisticMessage[](messages,(state: Message[], newMessage: string) [...state,{ message: newMessage },])return (div{optimisticMessages.map((m, k) (div key{k}{m.message}/div))}formaction{async (formData: FormData) {const message formData.get(message)addOptimisticMessage(message)await send(message)}}input typetext namemessage /button typesubmitSend/button/form/div) }嵌套元素 你可以在 form 中嵌套的元素中调用服务器操作如 button、input type“submit” 和 input type“image”。这些元素接受 formAction prop 或事件处理程序。 这在你想在一个表单中调用多个服务器操作的情况下很有用。例如你可以创建一个特定的 button 元素用于保存后草稿并发布它。请参阅 React form 文档了解更多信息。 无表单元素 虽然在 form 元素中使用服务器操作很常见但它们也可以从代码的其他部分调用如事件处理程序和 useEffect。 事件处理程序 你可以从事件处理程序如onClick调用服务器操作。例如要增加类似计数 // app/like-button.tsxuse clientimport { incrementLike } from ./actions import { useState } from reactexport default function LikeButton({ initialLikes }: { initialLikes: number }) {const [likes, setLikes] useState(initialLikes)return (pTotal Likes: {likes}/pbuttononClick{async () {const updatedLikes await incrementLike()setLikes(updatedLikes)}}Like/button/) }为了改善用户体验我们建议使用其他 React API如useOptimistic 并使用 Transition 以在服务器上完成服务器操作执行之前更新 UI或显示挂起状态。 你还可以将事件处理程序添加到表单元素中例如在 onChange上保存表单字段 // app/ui/edit-post.tsxuse clientimport { publishPost, saveDraft } from ./actionsexport default function EditPost() {return (form action{publishPost}textareanamecontentonChange{async (e) {await saveDraft(e.target.value)}}/button typesubmitPublish/button/form) }对于这种情况其中可能会快速连续触发多个事件我们建议使用防抖来阻止不必要的服务器操作调用。 useEffect 你可以使用 React useEffect hook 在组件装载或依赖项更改时调用服务器操作。这对于依赖于全局事件或需要自动触发的突变很有用。例如onKeyDown 用于应用程序快捷方式交叉点观察者挂钩用于无限滚动或者当组件安装以更新视图计数时 // app/view-count.tsxuse clientimport { incrementViews } from ./actions import { useState, useEffect } from reactexport default function ViewCount({ initialViews }: { initialViews: number }) {const [views, setViews] useState(initialViews)useEffect(() {const updateViews async () {const updatedViews await incrementViews()setViews(updatedViews)}updateViews()}, [])return pTotal Views: {views}/p }记住要考虑 useEffect 的行为和注意事项。 错误处理 当抛出错误时它将被客户端上最近的 error.js 或 Suspense 边界捕获。我们建议使用 try/catch 返回要由 UI 处理的错误。 例如你的服务器操作可能会通过返回消息来处理创建新项目时的错误 // app/actions.tsuse serverexport async function createTodo(prevState: any, formData: FormData) {try {// 突变数据} catch (e) {throw new Error(Failed to create task)} }需要知道 除了抛出错误之外你还可以返回一个由 useFormStatus 处理的对象。请参阅服务器端验证和错误处理。 重新验证数据 你可以使用 revalidatePath API 重新验证服务器操作中的 Next.js 缓存 // app/actions.tsuse serverimport { revalidatePath } from next/cacheexport async function createPost() {try {// ...} catch (error) {// ...}revalidatePath(/posts) }或者使用 revalidateTag 使具有缓存标记的特定数据提取无效 // app/actions.tsuse serverimport { revalidateTag } from next/cacheexport async function createPost() {try {// ...} catch (error) {// ...}revalidateTag(posts) }重定向 如果你希望在完成服务器操作后将用户重定向到不同的路由则可以使用 redirect API。redirect 需要在 try/catch 块之外调用 // app/actions.tsuse serverimport { redirect } from next/navigation import { revalidateTag } from next/cacheexport async function createPost(id: string) {try {// ...} catch (error) {// ...}revalidateTag(posts) // 更新缓存的帖子redirect(/post/${id}) // 导航到新的文章页面 }Cookies 你可以使用 cookies API 中的 get、set和 delete 服务器操作中的 cookies // app/actions.tsuse serverimport { cookies } from next/headersexport async function exampleAction() {// Get cookieconst value cookies().get(name)?.value// Set cookiecookies().set(name, Delba)// Delete cookiecookies().delete(name) }请参阅有关从服务器操作中删除 cookie 的其他示例。 安全 认证与授权 你应该像对待公开的 API 端点一样对待服务器操作并确保用户有权执行该操作。例如 // app/actions.tsuse serverimport { auth } from ./libexport function addItem() {const { user } auth()if (!user) {throw new Error(You must be signed in to perform this action)}// ... }闭包和加密 在组件内定义服务器操作会创建一个闭包其中操作可以访问外部函数的范围。例如publish 操作可以访问 publishVersion 变量 // app/page.tsxexport default function Page() {const publishVersion await getLatestVersion();async function publish(formData: FormData) {use server;if (publishVersion ! await getLatestVersion()) {throw new Error(The version has changed since pressing publish);}...}return button action{publish}Publish/button; }当你需要在渲染时捕获数据快照例如publishVersion以便稍后调用操作时使用时闭包非常有用。 然而为了实现这一点在调用操作时捕获的变量会被发送到客户端并返回到服务器。为了防止敏感数据暴露给客户端Next.js 自动对封闭变量进行加密。每次构建 Next.js 应用程序时都会为每个操作生成一个新的私钥。这意味着只能对特定的生成调用操作。 需要知道 我们不建议仅依靠加密来防止敏感值在客户端上暴露。相反你应该使用 React taint API 来主动防止特定数据发送到客户端。 重写加密密钥高级 当跨多个服务器自托管 Next.js 应用程序时每个服务器实例最终可能会使用不同的加密密钥从而导致潜在的不一致性。 为了缓解这种情况可以使用 process.env.NEXT_SERVER_ACTIONS_encryption_key 环境变量覆盖加密密钥。指定此变量可确保加密密钥在构建中是持久的并且所有服务器实例都使用相同的密钥。 这是一个高级用例其中跨多个部署的一致加密行为对您的应用程序至关重要。您应该考虑标准的安全实践如密钥轮换和签名。 需要知道 部署到 Vercel 的 Next.js 应用程序会自动处理此问题。 允许的来源高级 由于服务器操作可以在 form 元素中调用这会使它们受到 CSRF 攻击。 在后台服务器操作使用 POST 方法并且只允许此 HTTP 方法调用它们。这可以防止现代浏览器中的大多数 CSRF 漏洞尤其是SameSite cookie 是默认的。 作为一种额外的保护Next.js 中的 Server Actions 还比较了 Origin 头到 Host 头或 X-Forwarded-Host。如果这些不匹配请求将被中止。换句话说服务器操作只能在承载它的页面所在的主机上调用。 对于使用反向代理或多层后端架构的大型应用程序其中服务器 API 与生产域不同建议使用配置选项serverActions.allowedOrigins 选项来指定安全来源列表。该选项接受一个字符串数组。 // next.config.js/** type {import(next).NextConfig} */ module.exports {experimental: {serverActions: {allowedOrigins: [my-proxy.com, *.my-proxy.com],},}, }了解有关安全和服务器操作的详细信息。 额外资源 有关服务器操作的更多信息请查看以下 React 文档 use serverformuseFormStatususeFormStateuseOptimistic 数据获取模式和最佳实践 React 和 Next.js 中有一些获取数据的推荐模式和最佳实践。本页将介绍一些最常见的模式以及如何使用它们。 在服务器上获取数据 只要可能我们建议在服务器上获取数据。这允许你 可以直接访问后端数据资源如数据库。 通过防止敏感信息如访问令牌和 API 密钥暴露给客户端使你的应用程序更加安全。 在同一环境中获取数据并进行渲染。这既减少了客户端和服务器之间的来回通信也减少了客户端上主线程的工作。 使用单个往返而不是在客户端上执行多个单独的请求来执行多个数据提取。 减少客户端-服务器瀑布。 根据你所在的地区数据获取也可以在离数据源更近的地方进行从而减少延迟并提高性能。 你可以使用服务器组件、路由处理程序和服务器操作在服务器上获取数据。 在需要的地方获取数据 如果你需要在树中的多个组件中使用相同的数据例如当前用户则不必全局获取数据也不必在组件之间转发 props。相反你可以在需要数据的组件中使用 fetch 或 React cache而不用担心对同一数据发出多个请求的性能影响。 这是可能的因为 fetch 请求是自动存储的。了解有关请求备忘录的更多信息。 需要知道 这也适用于布局因为不可能在父布局及其子布局之间传递数据。 Streaming Streaming 和 Suspense 是 React 的功能允许你逐步渲染和递增地将 UI 的渲染单元流式传输到客户端。 使用服务器组件和嵌套布局你可以立即渲染页面中不特别需要数据的部分并显示页面中正在获取数据的部分的加载状态。这意味着用户不必等待整个页面加载后才能开始与之交互。 要了解有关 Streaming 和 Suspense 的更多信息请参阅加载 UI 和 Streaming 与 Suspense 页面。 并行和顺序数据获取 在 React 组件内部获取数据时需要注意两种数据获取模式并行Parallel和顺序Sequential。 通过顺序数据获取路由中的请求是相互依赖的因此会创建瀑布。在某些情况下你可能需要此模式因为一次提取取决于另一次提取的结果或者您希望在下一次提取之前满足一个条件以节省资源。然而这种行为也可能是无意的并导致更长的加载时间。 通过并行数据获取路由中的请求被急切地启动并将同时加载数据。这减少了客户端-服务器瀑布和加载数据所需的总时间。 顺序数据获取 如果你有嵌套的组件并且每个组件都获取自己的数据那么如果这些数据请求不同则数据提取将按顺序进行这不适用于对相同数据的请求因为它们会自动存储。 例如Playlists 组件只有在 Artist 组件完成获取数据后才会开始获取数据因为 Playlists 取决于 artistID prop // app/artist/[username]/page.tsxasync function Playlists({ artistID }: { artistID: string }) {// 等待播放列表const playlists await getArtistPlaylists(artistID)return (ul{playlists.map((playlist) (li key{playlist.id}{playlist.name}/li))}/ul) }export default async function Page({params: { username }, }: {params: { username: string } }) {// 等待艺术家const artist await getArtist(username)return (h1{artist.name}/h1Suspense fallback{divLoading.../div}Playlists artistID{artist.id} //Suspense/) }在这种情况下你可以使用 loading.js用于路由段或 React Suspense用于嵌套组件来显示即时加载状态同时 React 在结果中进行流式传输。 这将防止整个路由被数据获取阻塞并且用户将能够与页面中未被阻塞的部分进行交互。 阻止数据请求 防止瀑布的另一种方法是在应用程序的根全局获取数据但这将阻止其下所有路由段的渲染直到数据完成加载。这可以被描述为 “要么全取要么全无” 的数据获取。要么你拥有页面或应用程序的全部数据要么没有。 任何带有 await 的请求获取都将阻止其下整个树的渲染和数据提取除非它们被封装在 Suspense 边界中或使用 loading.js。另一种选择是使用并行数据获取或预加载模式。 并行数据获取 要并行获取数据你可以通过在使用数据的组件外部定义请求然后从组件内部调用请求来更早地启动请求。这通过并行启动请求来节省时间但是在所有的 promises 都 resolved 之前用户不会看到渲染的结果。 在下面的示例中getArtist 和 getArtistAlbums 函数在 Page 组件外部定义然后在组件内部调用我们等待这两个承诺得到解决 // app/artist/[username]/page.tsximport Albums from ./albumsasync function getArtist(username: string) {const res await fetch(https://api.example.com/artist/${username})return res.json() }async function getArtistAlbums(username: string) {const res await fetch(https://api.example.com/artist/${username}/albums)return res.json() }export default async function Page({params: { username }, }: {params: { username: string } }) {// 并行启动多个请求const artistData getArtist(username)const albumsData getArtistAlbums(username)// 等待所有的 promises 都 resolveconst [artist, albums] await Promise.all([artistData, albumsData])return (h1{artist.name}/h1Albums list{albums}/Albums/) }为了改善用户体验可以添加 Suspense Boundary 以分解渲染工作并尽快渲染部分结果。 预加载数据 防止瀑布的另一种方法是使用预加载模式。你可以选择创建一个 preload 函数来进一步优化并行数据获取。有了这种方法你就不必把承诺当作 props。preload 函数也可以有任何名称因为它是一个模式而不是 API。 // components/Item.tsximport { getItem } from /utils/get-itemexport const preload (id: string) {// void 计算给定的表达式并返回 undefined// https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators/voidvoid getItem(id) } export default async function Item({ id }: { id: string }) {const result await getItem(id)// ... }// app/item/[id]/page.tsximport Item, { preload, checkIsAvailable } from /components/Itemexport default async function Page({params: { id }, }: {params: { id: string } }) {// 开始加载项数据preload(id)// 执行另一个异步任务const isAvailable await checkIsAvailable()return isAvailable ? Item id{id} / : null }使用 React cache、server-only 和预加载模式 你可以将 cache 功能、preload 模式和 server-only 的包结合起来创建一个可在整个应用程序中使用的数据获取实用程序。 // utils/get-item.tsimport { cache } from react import server-onlyexport const preload (id: string) {void getItem(id) }export const getItem cache(async (id: string) {// ... })使用这种方法你可以更早地获取数据、缓存响应并确保这种数据获取只发生在服务器上。 Layouts、Pages 或其他组件可以使用 utils/get-item 导出来控制何时获取项的数据。 需要知道 我们建议使用 server-only 的包以确保客户端永远不会使用服务器数据获取功能。 防止敏感数据暴露给客户端 我们建议使用 React 的 taint API即 taintObjectReference 和 taintUniqueValue以防止整个对象实例或敏感值被传递到客户端。 要在应用程序中启用 tainting请将 Next.js 配置 experial.taint 选项设置为 true // next.config.jsmodule.exports {experimental: {taint: true,}, }然后将要 taint 的对象或值传递给 experimental_taintObjectReference 或 experimental_taintUniqueValue 函数 // app/utils.tsimport { queryDataFromDB } from ./api import {experimental_taintObjectReference,experimental_taintUniqueValue, } from reactexport async function getUserData() {const data await queryDataFromDB()experimental_taintObjectReference(Do not pass the whole user object to the client,data)experimental_taintUniqueValue(Do not pass the users phone number to the client,data,data.phoneNumber)return data }// app/page.tsximport { getUserData } from ./dataexport async function Page() {const userData getUserData()return (ClientComponentuser{userData} // 这将导致一个错误因为 tainObjectReferencephoneNumber{userData.phoneNumber} // 这将导致一个错误因为 tainUniqueValue/) }了解有关安全和服务器操作的详细信息。
http://www.zqtcl.cn/news/982279/

相关文章:

  • 网站服务器地址在哪里看艺术学校网站模板
  • 郑州中心站网站建设价格标准新闻
  • 电子商务网站管理互联网营销师主要做什么
  • 门户网站指的是什么凯里网络公司建设网站
  • 网站接入服务商查询0建设营销型网站步骤
  • 长沙如何做百度的网站小型网站建设实训教程
  • 昆明网络公司网站网站建设经费请示
  • 手机端网站欣赏wordpress 文章rss
  • 做网站一定要实名认证吗国外免费空间网站申请
  • 阿里云网站空间主机长春网站建设设计
  • 龙华网站建设yihekj长沙招聘网站制作
  • 网站怎么做文本跳出来网络规划设计师有用吗
  • 室内设计网站官网大全中国那些企业做网站做得好
  • 状态管理名词解释网站开发网络营销推广方案案例
  • 做网站需要几大模板河南中国建设信息网
  • 成都温江网站建设空间网页版
  • 做美股的数据网站邢台网站建设公司哪家好一点
  • 青岛即墨网站开发查询建设用地规划许可证在哪个网站
  • 成都APP,微网站开发芜湖企业100强
  • 江门搜索引擎网站推广网约车多少钱一辆
  • 北京高端网站建设宣传请人做软件开发的网站
  • h网站建设长沙本地公众号
  • 苏州工业园区劳动局网站做不了合同建域名做网站
  • 内蒙古建设兵团网站组建网站开发团队
  • 劳务派遣做网站的好处广州最新新闻事件
  • 海兴网站建设公司网站建设原则
  • 网站建设完不管了自己怎么接手wordpress个人主页
  • 具有品牌的网站建设霞浦建设局网站
  • 推荐个网站免费的wordpress force ssl
  • app网站搭建做英文网站的心得