跳至正文

Server Component

大多数uiify组件是Server Component,不提供客户端JavaScript。需要JavaScript的组件会在导入路径中明确标示。

根入口是客户端边界

从@gunkin/uiify导入很方便,同时也会标记一个客户端边界。在Server Component中,应从组件自身的入口导入;该入口不含"use client"指令。

// convenient: a client boundary
import { Accordion } from "@gunkin/uiify";

// server-compatible: no client JavaScript
import { Accordion } from "@gunkin/uiify/components/accordion";

受控变体位于/client下

受控组件始终需要客户端边界,因为必须有代码保存值并触发重新渲染。因此,受控变体位于/client子路径下,而不是通过prop切换。

import { Modal } from "@gunkin/uiify/components/modal"; // uncontrolled, 0 kB
import { ModalClientContent } from "@gunkin/uiify/components/modal/client"; // controlled

这样,水合成本直接体现在你写下的导入语句中,无须等到打包报告才发现。水合前能够工作的是非受控组件。

跨边界组合

Client Component可以渲染通过children传入的Server Component,使交互外壳保持轻量,同时将内容留在服务端。

// server component
<ClientShell>
  <ExpensiveServerRenderedThing />
</ClientShell>

避免React context

Tier 0禁用React context:Server Component不能使用context,因此通过provider通信的组成部分无法在服务端渲染。它们改用HTML属性和确定性id连接。

基于@gunkin/uiify/elements构建时也应遵循同一规则:浏览器无须JavaScript就能解析commandfor、popovertarget、for和name。查看架构

水合前

Tier 0组件完整通过禁用JavaScript的测试套件:既可见,也可操作。Tier 1保留原生状态行为,只缺少客户端孤岛添加的能力。Tier 2渲染有意义的标记;键盘导航、过滤和ARIA同步需等到水合后。

每个组件页面都展示级别和实测预算;验证依据说明了两者的来源。