React DOM 集成
createPortal 是什么, 有什么作用;
- createPortal:
createPortal(children, domNode, key?)把内容放进指定已有 DOM 节点,适合弹窗、提示层等需要跳出裁剪容器的 UI; - 树关系: Context 与事件仍按 React 树传播,Portal 内点击可能触发 React 祖先处理器,并非只沿 DOM 容器关系理解;
- 容器身份: 换用另一个 domNode 会重新创建 Portal 内容;弹窗仍需自行处理焦点、键盘与无障碍语义;
import { createPortal } from "react-dom";
function Overlay({ children }) {
return createPortal(children, document.body);
}
如何强制同步提交 DOM?
- flushSync: 包裹更新后,在下一行代码前让相关 DOM 同步更新,主要服务于必须即时观察 DOM 的浏览器或第三方集成;
- 成本: 可能冲刷回调外的待处理更新与 Effect,迫使 Suspense 显示 fallback,并损害吞吐,不作为日常更新默认方式;
- 调用限制: 不在 React 正在渲染或执行 Effect 时调用,避免试图嵌套提交;
import { flushSync } from "react-dom";
function addAndScroll() {
flushSync(() => setItems((items) => [...items, newItem]));
listRef.current.lastElementChild?.scrollIntoView();
}
如何选择资源提示的准备程度?
| API | 准备程度 | 典型用途 |
|---|---|---|
| prefetchDNS | DNS 查询 | 很可能访问的域名 |
| preconnect | 建立连接 | 即将获取跨域资源 |
| preload | 获取资源但不执行 | 字体、图片、样式、脚本 |
| preloadModule | 获取模块但不执行 | 即将使用的 ESM |
| preinit | 获取并应用或执行 | 样式表、脚本 |
| preinitModule | 获取并执行模块 | 需要初始化的 ESM |