Happy Almost New Year everyone!
I made a library that integrates Surface + LiveView nicely with React.
I have aptly named it ReactSurface
There are some other libraries that do this, or similar (phoenix_live_react).
ReactSurface is different in that it is a first class Surface component, and relies on the surface templating and component engine to work (does not rely on phoenix content_tag/3
). Another difference is that it does not create sibling DOM nodes - it creates a nested react container, inside a live_view
tracked container. keeping this data and context a bit more contained in the DOM. (see the README for an example)
ReactSurface uses react hydration(ReactDOM.hydrate
) to keep the react internal component state intact between updates. It also exposes the live_view js functions (handleEvent, pushEvent, pushEventTo)
to all components rendered in the react tree via a React Context accessible via a react hook: useLiveContext
Check out the demo app at ./demo
to see it in action!
Motivation
Been playing with LiveView + Surface, and they are great - but not sure I can convince my employer to go all in on it⦠This is a bit of a compromise to allow using React components for UI heavy bits of the page - but keeping the main layout, routing and data layer a server side concern.
Future ideas
- Use a Surface Macro component to perform a server render with some default props at compile time.
- This would provide compile time server side React rendering - but only for a default state and allow for the initial mounted phx hook to perform a
ReactDOM.hydrate
on the server rendered content. - the benefit of server side react rendering, without the complexity of stringing together a node server/stdio API to perform initial rendering of client side react components in production.
- I might have the idea of a Surface Macro component wrong. @msaraiva would this work how I am imagining?
- This would provide compile time server side React rendering - but only for a default state and allow for the initial mounted phx hook to perform a
- Dynamic loading of react components -
ReactSurface
does not rely on your React components existing on thewindow
to work - thebuildHook
function takes a parameter where you supply a map of your components.- this coupling is not ideal - would prefer performing a dynamic import of the component based on the name passed to the Surface Component via something like
React.lazy
- this coupling is not ideal - would prefer performing a dynamic import of the component based on the name passed to the Surface Component via something like
Feedback + ideas are much appreciated!
I do not suggest using this in prod just yet - more of a beta at the moment.
Will publish to hex once I have some tests in place.
Thanks for for checking it out!