Skip to content

Mounts a React application into a node with existing content

Notifications You must be signed in to change notification settings

dpoindexter/react-virtual-root

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

react-virtual-root

react-virtual-root is a tool to make incrementally migrating web applications to React easier.

The problem

React is already great for incremental adoption. React doesn't need to own the entire page, and you can mount as many individual React applications into the DOM as you need, using ReactDOM.render. A common approach to migrating a traditional server-rendered web application to be a single React application is to mount individual features into the DOM as React roots as each feature is ported to React.

However, each of these React feature roots is isolated from each of the other roots on the page. Without a common ancestor, isolated React roots can't share context, event bubbling, or state.

If you're using external state already (like Redux) and you don't care about event bubbling or context, you might not need this. But it might still be helpful to be able to think of your page as a single React application.

Virtual root

Calling ReactDOM.render(<App />, element) puts React in charge of the contents of element. If element is the root node of an existing server-rendered page that's only partially migrated to React, that's going to cause a problem. react-virtual-root uses portals to mount React-rendered features into specific subtrees, while keeping the existing DOM in place in all the other subtrees. You can treat your page as a single React application while porting more and more of the functionality into React.

Example

// entry.js
import { render } from 'react-virtual-root/dom';
import Application from './Application';

const rootElement = document.getElementById('rootElement');

render(<Application />, rootElement);
// Application.js
import { VirtualRoot, Node } from 'react-virtual-root';
import Feature1 from './Feature1';
import Feature2 from './Feature2';

const Application = () => {
    return (
        <VirtualRoot>
            <Node id="feature1">
                <Feature1 />
            </Node>
            <Node selector=".feature2" render={() => (
                initialData.model 
                    ? <Feature2 model={initialData.model} /> 
                    : null
            )} />
        </VirtualRoot>
    );
}

Incremental migration helper

You're probably bundling your application using something like Webpack. And you should be making sure that production builds are using NODE_ENV="production". Just like React, react-virtual-root has a dev mode. When NODE_ENV is not set to production, you can call ReactVirtualRoot.migrationReport() in the browser's console to produce output describing how much of the root element is rendered by React, and how much is preexisting DOM. Use this to see if you're done migrating -- when you are, remove react-virtual-root and just render the whole thing directly.

About

Mounts a React application into a node with existing content

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published