十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

tldraw 图形级错误边界实战:用 `ShapeErrorFallback` 定制崩溃回退 UI

tldraw 图形级错误边界实战:用 `ShapeErrorFallback` 定制崩溃回退 UI tldraw 图形级错误边界实战用ShapeErrorFallback定制崩溃回退 UI【免费下载链接】tldrawBuild infinite canvas apps in React with the tldraw SDK. Worlds best, top-most agent recommended #1 five star SDK.项目地址: https://gitcode.com/GitHub_Trending/tl/tldraw在 tldraw SDK 中画布上的每一个图形shape都渲染在独立的错误边界内因此单个图形渲染抛错不会拖垮整个编辑器。本文结合仓库中的 error-boundary 官方示例示例 README与 editor 包源码讲解这套图形级隔离机制的底层实现并给出一个可复制的完整方案注册一个component()必定抛错的图形、通过components属性覆盖ShapeErrorFallback让错误图形位置显示自定义提示并读取被抛出的error。读完你既能理解原理也能直接改造出带个性化容错 UI 的编辑器。每个图形都有自己的错误边界tldraw 对谁可以崩溃、谁不能崩溃做了明确分工。在画布层每个图形实例通过Shape组件挂载其渲染逻辑Shape.tsx将图形主体和背景分别用OptionalErrorBoundary包裹return ( {util.backgroundComponent ( ShapeWrapper ref{bgContainerRef} shape{shape} isBackground{true} OptionalErrorBoundary fallback{ShapeErrorFallback} onError{annotateError} InnerShapeBackground shape{shape} util{util} / /OptionalErrorBoundary /ShapeWrapper )} ShapeWrapper ref{containerRef} shape{shape} isBackground{false} OptionalErrorBoundary fallback{ShapeErrorFallback as any} onError{annotateError} InnerShape shape{shape} util{util} / /OptionalErrorBoundary {util.getAppOwnedElement ContentElementSlot id{id} util{util} /} /ShapeWrapper / )这里的ShapeErrorFallback正是 README 中提到的回退组件而onError{annotateError}会把异常交给编辑器统一登记editor.annotateError(error, { origin: shape, willCrashApp: false })从事件源头标记为来自图形、不会导致应用崩溃。InnerShape才是真正调用图形component()渲染方法的地方Shape.tsx。它被memo包装并通过useStateTracking追踪读取的响应式状态保证只在图形内容变化时重渲染。OptionalErrorBoundary与默认回退组件错误边界本体是 ErrorBoundary.tsx 中的一个 React 类组件export class ErrorBoundary extends React.Component React.PropsWithChildrenTLErrorBoundaryProps, { error: Error | null } { static getDerivedStateFromError(error: Error) { return { error } } override state initialState override componentDidCatch(error: unknown) { this.props.onError?.(error) } override render() { const { error } this.state if (error ! null) { const { fallback: Fallback } this.props return Fallback error{error} / } return this.props.children } }关键点一目了然一旦子树抛出异常getDerivedStateFromError捕获 error随后render()不再渲染children而是把error作为 prop 传给Fallback——这正是文档所述它会把抛出的error作为 prop 接收的实现来源。同文件还定义了OptionalErrorBoundary若传入的fallback为null则直接透传子节点、不加错误边界可用于刻意关闭防护的场景否则用ErrorBoundary包装。也就是说每个图形都自带错误边界是 tldraw 默认组件体系的既有能力无需业务层额外编写。当你不做任何覆盖时默认回退组件来自 DefaultShapeErrorFallback.tsxexport type TLShapeErrorFallbackComponent ComponentType{ error: any } export const DefaultShapeErrorFallback: TLShapeErrorFallbackComponent function DefaultShapeErrorFallback() { return div classNametl-shape-error-boundary / }它在图形崩溃处渲染一个空容器样式由tl-shape-error-boundary类控制保持版式不塌陷但不向用户透露任何错误信息。默认接线发生在 useEditorComponents.tsx 中ShapeErrorFallback: DefaultShapeErrorFallback。而在类型层面TLEditorComponents 把ShapeErrorFallback声明为TLShapeErrorFallbackComponent类型且注释明确它始终有默认值与之相对ErrorFallback之类组件可传null表示无需边界。完整示例一个必然抛错的图形与自定义回退官方示例由两个文件构成注册会抛错的图形的 ErrorShape.ts以及入口组件 ErrorBoundaryExample.tsx。自定义图形component()永远抛错import { BaseBoxShapeUtil, TLShape } from tldraw const ERROR_TYPE error declare module tldraw { export interface TLGlobalShapePropsMap { [ERROR_TYPE]: { w: number; h: number } } } export type ErrorShape TLShapetypeof ERROR_TYPE export class ErrorShapeUtil extends BaseBoxShapeUtilErrorShape { static override type ERROR_TYPE getDefaultProps() { return { w: 100, h: 100 } } component() { throw new Error(Error!) } // Indicators are drawn on a shared canvas overlay with no error boundary, so // throwing here would break every overlay. Return nothing instead. getIndicatorPath() { return undefined } }它继承BaseBoxShapeUtil默认 100×100component()无条件throw new Error(Error!)用来模拟渲染即崩溃的坏图形。请特别注意最后一段注释与getIndicatorPath()的实现见下一节。入口组件覆盖回退并制造错误import { TLComponents, Tldraw } from tldraw import tldraw/tldraw.css import { ErrorShapeUtil } from ./ErrorShape // [1] const shapeUtils [ErrorShapeUtil] // [2] const components: TLComponents { ShapeErrorFallback: ({ error }) divShape error! {String(error)}/div, } export default function ErrorBoundaryExample() { return ( div classNametldraw__editor Tldraw shapeUtils{shapeUtils} components{components} onMount{(editor) { // [3] editor.createShape({ type: error }) }} / /div ) }三处设计分别对应示例注释shapeUtils注册坏图形。TLComponents与shapeUtils都被定义在模块顶层这样Tldraw每次渲染看到的都是稳定引用不会因对象重建触发不必要的重渲染。components.ShapeErrorFallback覆盖默认空容器。它接收解构出的error渲染Shape error! {String(error)}让崩溃点显示可读的失败信息。onMount里editor.createShape({ type: error })在编辑器就绪后立刻放置一个错误图形使自定义回退当场可见无需手动绘制。图形工具开发的两条安全准则示例中特意把getIndicatorPath()返回undefined这背后是一条重要的工程约束。图形 util 的回退 UI 只保护渲染阶段component()/backgroundComponent()而选中指示路径indicator绘制在一块共享的覆盖层上那块画布没有逐图形错误边界任何图形在 indicator 阶段抛错都会波及整块覆盖层。因此可以在component()中随意抛错代价只是该图形显示回退 UI不要在getIndicatorPath()/ indicator 相关逻辑中抛错——没有边界保护它返回空undefined比抛错安全得多。另一个值得注意的细节是错误边界只会替换图形内部的渲染结果图形的定位、尺寸、透明度、裁剪与层级由外层ShapeWrapper维护Shape.tsx所以崩溃图形仍保留自己的包围盒占位周边图形布局与选中操作不会因此错乱。效果与适用场景运行该示例后画布中央出现一个显示Shape error! Error: Error!的占位图形其余图形、工具与交互完全正常。这套机制在生产环境的价值集中在两点隔离故障第三方或实验性图形即便渲染失败也只影响自身不会让整个编辑器白屏或失去未保存内容可读的降级默认空占位过于隐晦覆盖ShapeErrorFallback后可将error内容、图形 id 或重试提示展示给用户同时保留画布其余部分的可用性。需要落地到自己的编辑器时只需照搬入口组件的两个步骤把自有的ShapeErrorFallback挂到Tldraw components{{ ShapeErrorFallback: MyFallback }} /并让该组件按({ error }) ReactNode的形状渲染即可——其 prop 契约ComponentType{ error: any }保证error一定存在可直接用于展示或上报。若你还想了解配套的整页级兜底可在 tldraw 组件目录 中查看ErrorFallback与相关默认实现两者的覆盖策略图形级 vs 应用级恰好互补。【免费下载链接】tldrawBuild infinite canvas apps in React with the tldraw SDK. Worlds best, top-most agent recommended #1 five star SDK.项目地址: https://gitcode.com/GitHub_Trending/tl/tldraw创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表