DOM 主机中自定义 React 渲染器的目的是什么?

What is the purpose of a custom React renderers within a DOM host?

序曲

我们都熟悉 React 自带的默认渲染器——ReactDOM。

我们还有自定义的 React 渲染器,可用于与 "hosts" that aren't the DOM environment, such as mobile devices (famously React Native), VR devices, the terminal (like ink) 交互,等等。

但是,在浏览器主机中,有一些自定义渲染器在 ReactDOM 内运行(或代替 ReactDOM 运行)。


核心问题

在浏览器主机内运行的自定义呈现器的目的是什么?


例子

在浏览器主机内运行的自定义呈现器的一些著名示例是:

来自 react-three-fiber threejs 元素的以下片段在 React 中声明,并且在幕后它将“映射”到特定的 canvas 操作:

<Canvas>
    <ambientLight />
    <pointLight position={[10, 10, 10]} />
    <Box position={[-1.2, 0, 0]} />
    <Box position={[1.2, 0, 0]} />
</Canvas>

react-three-fiber 正在使用自定义渲染器来实现上述目标,但我 认为 它也可以通过副作用来实现。 Box 可以有一个 useEffect 对 threejs 实例执行操作。

可能性/假设

那么为什么 选择自定义渲染器? 我相信它可能是以下的零个、一个或多个:

在 React 中使用自定义调节器有一些有趣的优势。正如您在 react-pixi-fiber 的 README.md 文件中所见,完全可以使用 ReactDOM 渲染 pixi 元素,而不是使用 react-pixi-fiber.[=12 中的自定义渲染=]

那为什么要创建自定义 renderer/reconciler?

在这种特定情况下,原因是 ReactDOM 并没有真正处理 canvas 元素。正如您所说,这可以通过自定义 hooks/components 的组合来实现。如果您阅读 react-three-fiber 的 why 部分,您会发现与自定义组件相比,通过使用他们的自定义调节器,您可以实现两件事:

  1. threejs 的所有内容都可以在这里使用,因为协调器内置了支持。
  2. 性能与直接使用 threejs 时相同,因为协调器可以更好地控制渲染内容和渲染时间。

您可以看看 here 那里深入解释了渲染和协调器之间的区别以及协调器如何细粒度地访问:组件生命周期,决定差异以及元素如何 added/removed 从视图(在 DOM、canvas、iOS 等)。

传统上 React 渲染器公开两个函数:render(children, target)unmountComponentAtNode(target)。 react-three-fiber 实际上也导出了这两个,它可以像那样使用,但是 threejs 特别需要大量的设置和样板,这在“Canvas”组件中更容易抽象。该组件担心设置所有内容、调整大小、事件等。它在 DOM 和 react-native 中工作。

Canvas 组件中的所有内容都是常规的 React。您拥有原生元素(网格、组、...)、组件、挂钩等。因此,当您在 Web 或其他任何地方使用 React 时,您可以获得与 React 相同的好处:将关注点打包到 re-usable、self-managed个组件。

我在上面发布了这个:twitter.com/0xca0a/status/1282999626782650368这应该很清楚为什么 React 总是比命令式布局膨胀更合适的选择。