我正在使用Next.js 13的app
目录,我想复制一些我在“经典”pages
目录中拥有的功能。我想显示一个由卡片组成的网格,每个卡片代表一组主机。我想在后台ping主机,每张卡都应该显示主机是否可达。
一张卡片看起来像这样:app/clients/client-card.tsx
:
"use client";
import { Card, CardBody } from "../components";
import { Chip } from "@material-tailwind/react";
export type ClientProps = {
label: string;
available?: boolean | undefined;
};
export default function ClientCard({ label, available }: ClientProps) {
return (
<Card key={label} title={label}>
<CardBody>
<h4>{label}</h4>
<Chip
color={available === undefined ? "gray" : available ? "green" : "red"}
className="mt-2"
value={available === undefined ? "Checking" : available ? "Online" : "Offline"}
/>
</CardBody>
</Card>
);
}
app/clients/page.tsx
中的服务器代码:
import fs from "fs";
import path from "path";
import { load } from "js-yaml";
import ClientCard from "./client-card";
type AnsibleInventory = {
probes?: {
hosts: Record<string, unknown>;
};
};
async function getInventory() {
const inventoryFile = path.join(
__dirname,
"..",
"..",
"..",
"..",
"..",
"example",
"inventory",
"hosts.yml"
);
const inventory = load(
fs.readFileSync(inventoryFile, "utf8")
) as AnsibleInventory;
return inventory;
}
export default async function Clients() {
const inventory = await getInventory();
const isAvailable = async (client: string): Promise<boolean> => {
const sleep = (ms: number) =>
new Promise((resolve) => setTimeout(resolve, ms));
await sleep(1000 + Math.random() * 1000);
return Math.random() > 0.5;
};
return (
<div>
<h1>Clients</h1>
{inventory.probes?.hosts === undefined ? (
<p>No clients found</p>
) : (
<div className="grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3">
{Object.keys(inventory.probes?.hosts).map((client) => (
<div key={client} className="col-span-1">
<ClientCard
key={client}
label={client}
available={isAvailable(client)}
/>
</div>
))}
</div>
)}
</div>
);
}
问题是,我希望页面首先加载,每张卡显示一个“检查”状态和灰色芯片,并传播检查结果。每一张卡片上都有。但是我不能异步调用isAvailable()
函数它需要一个同步值。我不能在服务器端使用useState
和效果。
以前,我可能会创建一个专用的api
路由,并从每个客户端卡向服务器发出一个请求,以从API获取fetch
的可用性状态。
有没有简单的方法可以做到这一点?特别是,这是一个潜在的长名单卡为个别主机.
我看到在其中一个streaming examples中,fetch
被传递到各个组件,但这些组件似乎也是服务器端的。在我的例子中,我显然必须使用"use client";
,因为@material-tailwind/react
库使用了一些客户端副作用,所以我不能将其作为服务器组件。
1条答案
按热度按时间qxsslcnc1#
现在似乎没有明显的解决方案,除了分离库,这样我就不会在RSC中导入客户端库。