We are all familiar with the default renderers that comes with React - ReactDOM.
We also have custom React renderers that can be used to interface with "hosts" that aren't the DOM environment, such as mobile devices (famously React Native), VR devices, the terminal (like ink), and so on.
However, there are some custom renderers that operate within (or instead of) ReactDOM while in a browser host.
What is the purpose of custom renderers that operate within the browser host?
Some notable examples of custom renderers that operate within the browser host are:
The following snippet from react-three-fiber
threejs elements are declared in React and under the hood it will "map" to particular canvas operations:
<Canvas>
<ambientLight />
<pointLight position={[10, 10, 10]} />
<Box position={[-1.2, 0, 0]} />
<Box position={[1.2, 0, 0]} />
</Canvas>
react-three-fiber
is using a custom renderer to achieve the above, but I think it could also be achieved with side effects. Box could have a useEffect
that performs operations against the threejs instance.
So why choose a custom renderer? I believe it may be zero, one, or more of the following:
What does a React renderer look like? The React team exposes their react-reconciler as a function to allow third parties to create custom renderers. This reconciler function takes one argument: a Host Configuration object that's methods provide an interface with which React can render to a host environment.
A React component tree is made of host and non-host components. Host components are platform-specific components belonging to the host environment (like browsers, or mobile devices). In the case of a DOM host, these may be HTML elements such as div , or img .
React uses a declarative paradigm that makes it easier to reason about your application and aims to be both efficient and flexible. It designs simple views for each state in your application, and React will efficiently update and render just the right component when your data changes.
React elements are plain objects representing the component type (e.g. App ) and the props. User-defined components (e.g. App ) can be classes or functions but they all “render to” elements. “Mounting” is a recursive process that creates a DOM or Native tree given the top-level React element (e.g. <App /> ).
There are some interesting advantages when it comes to using a custom reconciler in React. As you see in the README.md file of react-pixi-fiber, it's totally possible to use ReactDOM to render the pixi elements instead of using the custom render from react-pixi-fiber.
Why create a custom renderer/reconciler then?
In this specific case the reason is that ReactDOM doesn't really deal with canvas elements. As you said though, that could have been achieved by a combination of custom hooks/components. If you read the why section of react-three-fiber you will see that by using their custom reconciler you can achieve two things, compared to custom components:
You can take a look here where there's an in depth explanation of the difference between render and reconcile and how the reconciler has fine grained access to: components lifecycles, decides the diffing and how elements are added/removed from the view (be in DOM, canvas, iOS etc).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With