cacheSignal

React Server Components

cacheSignal 目前仅与 React 服务器组件 一起使用。

cacheSignal 让你知道 cache() 的使用寿命何时结束。

const signal = cacheSignal();

参考

🌐 Reference

cacheSignal

调用 cacheSignal 获取一个 AbortSignal

🌐 Call cacheSignal to get an AbortSignal.

import {cacheSignal} from 'react';
async function Component() {
await fetch(url, { signal: cacheSignal() });
}

当 React 完成渲染后,AbortSignal 将被中止。这允许你取消任何不再需要的正在进行的工作。 渲染被认为完成的情况如下:

🌐 When React has finished rendering, the AbortSignal will be aborted. This allows you to cancel any in-flight work that is no longer needed. Rendering is considered finished when:

  • React 已成功完成渲染
  • 渲染已中止
  • 渲染失败

参数

🌐 Parameters

此函数不接受任何参数。

🌐 This function does not accept any parameters.

返回

🌐 Returns

cacheSignal 在渲染期间调用时返回 AbortSignal。否则,cacheSignal() 返回 null

注意事项

🌐 Caveats

  • cacheSignal 目前仅用于 React Server Components。在客户端组件中,它将始终返回 null。将来,当客户端缓存刷新或失效时,它也将用于客户端组件。你不应假设它在客户端总是为 null。
  • 如果在渲染之外调用,cacheSignal 将返回 null,以明确当前作用域不会被永久缓存。

用法

🌐 Usage

取消正在进行的请求

🌐 Cancel in-flight requests

调用 cacheSignal 以中止正在进行的请求。

🌐 Call cacheSignal to abort in-flight requests.

import {cache, cacheSignal} from 'react';
const dedupedFetch = cache(fetch);
async function Component() {
await dedupedFetch(url, { signal: cacheSignal() });
}

易犯错误

你不能使用 cacheSignal 来中止在渲染之外启动的异步工作,例如

import {cacheSignal} from 'react';
// 🚩 Pitfall: The request will not actually be aborted if the rendering of `Component` is finished.
const response = fetch(url, { signal: cacheSignal() });
async function Component() {
await response;
}

React 渲染完成后忽略错误

🌐 Ignore errors after React has finished rendering

如果一个函数抛出异常,可能是由于取消(例如 数据库连接 已关闭)。你可以使用 aborted 属性 来检查错误是由于取消还是实际错误。你可能想要 忽略 由于取消导致的错误。

import {cacheSignal} from "react";
import {queryDatabase, logError} from "./database";

async function getData(id) {
try {
return await queryDatabase(id);
} catch (x) {
if (!cacheSignal()?.aborted) {
// only log if it's a real error and not due to cancellation
logError(x);
}
return null;
}
}

async function Component({id}) {
const data = await getData(id);
if (data === null) {
return <div>No data available</div>;
}
return <div>{data.name}</div>;
}