Building a custom react renderer
This is what makes up React. There are two parts:
- Host Environments (one of the below)
- a set of host (built-in) components (div, p, span, img, etc) -> <span class="text-highlight">react web</span>
- a set of host (built-in) components (View, Text, Image) -> react native
- ... others for react ART, react pdf...
react web and react native have a different set of props and event handlers
- Reconciler (there's an npm package called
react-reconciler that is basically this)- function components
- class components
- props, state
- effects, lifecycles
- key, ref, context
- React.lazy, error boundaries
- concurrent mode, Suspense
Reconciler
the reconciler has two modes:
mutation mode
- this is what
raect-dom uses, because that's how the DOM works, through mutation.
view = createView()
updateView(view, { color: 'red' })
const div = document.createElement('div')
div.style.color = 'red'
persistent mode
- used if your target treats the view as a tree of persistent immutable objects
- instead of mutating in place, you create a new version of it each time you want to update.
- the next-gen version of react native uses this mode, because it's faster with concurrent mode
view = createView()
view2 = cloneView(view, { color: 'red' })
when you give React a new set of stuff to render
- react makes a diff
- react comes up with a list of commands that it needs to do to update the DOM
here's the toy version from Sophie's talk (plus my own bits playing around with it)
what this doesn't handle, that is handled in a full react-dom renderer
- handles all props
- form control
- quite a lot of logic needed to handle controlled and uncontrolled components
- refs
- attribute and event normalization for cross-browser compatibility
- svg support
- event bubbling through portals
- other edge cases