React Cache函数在Server Components中的请求去重
在React Server Components中,当多个组件需要相同数据时,可能会发送重复的网络请求,导致性能下降。cache函数可以帮助你解决这个问题,确保同一份数据只被请求一次。
什么是请求去重?
想象一下,你的应用中有两个组件都需要显示用户的个人资料。如果这两个组件同时渲染,它们可能会各自发起一次请求来获取用户数据。这会导致两次网络请求,即使数据是相同的。请求去重就是指,当多个组件需要相同数据时,只发送一次请求,其他组件复用这个结果,从而减少网络开销。
如何使用cache函数
cache函数是React提供的一个工具,用于包装数据获取函数,实现请求去重。
1. 创建一个数据获取函数
首先,创建一个简单的数据获取函数。这个函数将从模拟的API获取用户数据。
// lib/data.js
export async function fetchUserData(userId) {
console.log(`Fetching data for user ${userId}...`);
// 模拟网络延迟
await new Promise(resolve => setTimeout(resolve, 1000));
// 返回模拟的用户数据
return { id: userId, name: `User ${userId}` };
}
2. 在Server Component中使用未缓存的函数
接下来,创建一个Server Component,并在其中使用上述函数。为了展示重复请求的问题,我们将在同一个页面中渲染两个相同的组件。
// app/page.js
import { fetchUserData } from '@/lib/data';
export default async function HomePage() {
// 在同一个页面中渲染两个用户资料组件
return (
<div>
<h1>User Profiles</h1>
<UserProfile userId="1" />
<UserProfile userId="1" />
</div>
);
}
async function UserProfile({ userId }) {
const userData = await fetchUserData(userId);
return <div>{userData.name}</div>;
}
当你运行这个应用时,控制台会显示两次Fetching data for user 1...,因为UserProfile组件被渲染了两次,每次都调用了fetchUserData函数。
3. 使用cache包装数据获取函数
现在,我们使用cache函数来包装fetchUserData,实现请求去重。
// lib/data.js
import { cache } from 'react';
export async function fetchUserData(userId) {
console.log(`Fetching data for user ${userId}...`);
await new Promise(resolve => setTimeout(resolve, 1000));
return { id: userId, name: `User ${userId}` };
}
// 使用cache包装函数
export const getCachedUserData = cache(fetchUserData);
然后,修改page.js文件,使用新的缓存函数。
// app/page.js
import { getCachedUserData } from '@/lib/data';
export default async function HomePage() {
return (
<div>
<h1>User Profiles</h1>
<UserProfile userId="1" />
<UserProfile userId="1" />
</div>
);
}
async function UserProfile({ userId }) {
const userData = await getCachedUserData(userId);
return <div>{userData.name}</div>;
}
再次运行应用,你会发现控制台只显示一次Fetching data for user 1...。cache函数确保了即使UserProfile组件被渲染多次,getCachedUserData函数也只被调用一次,后续的调用会直接返回缓存的结果。
cache函数的工作原理
cache函数通过以下方式实现请求去重:
- 缓存键生成:
cache函数会根据你传递给被包装函数的参数生成一个缓存键。在上面的例子中,缓存键就是userId的值(例如"1")。 - 结果缓存:当
cache包装的函数被调用时,它会检查缓存中是否已经存在与当前参数匹配的结果。 - 缓存命中:如果缓存中存在匹配的结果,
cache函数会直接返回缓存的结果,而不会重新执行被包装的函数。 - 缓存未命中:如果缓存中不存在匹配的结果,
cache函数会执行被包装的函数,并将结果存储在缓存中,然后返回这个结果。
注意事项
- 顶层调用:
cache函数必须在Server Component的顶层调用,不能在事件处理函数、条件语句或循环中调用。 - 参数可序列化:
cache函数的参数必须是可序列化的,因为它们会被用作缓存键。这意味着你不能使用函数、Symbol或包含循环引用的对象作为参数。 - 数据一致性:
cache函数缓存的是数据获取的结果,而不是数据本身。如果后端数据发生变化,你需要重新请求数据。你可以通过设置较短的缓存时间或使用版本号来实现这一点。 - 作用域:
cache的缓存是针对请求的,而不是针对组件实例的。这意味着如果两个不同的页面请求相同的数据,它们会共享同一个缓存。
通过正确使用cache函数,你可以显著提高React Server Components应用的性能,减少不必要的网络请求。

暂无评论,快来抢沙发吧!