DEV Community

Clay Murray for DropConfig

Posted on • Updated on

Using React with Stimulus JS

I have written a few articles about how much I like Server Side Rendering (SSR) and using Stimulusjs.

But sometimes you need the power of React to help you. How can we include React when we need it without weighing down our website when we don't?

It's actually not too tough with built in code splitting in Webpack or parceljs. So let's go throught the basics.

Our Stimulus Controller

import {Controller} from "stimulus";

export default class extends Controller {
    //Load the React code when we initialize
    initialize(){
        this.reactComponentPromise = import("./reactComponent");
    }
    connect(){
        this.reactComponent = await this.reactComponentPromise;

        const reactRoot = this.targets.find("reactRoot");
        const props = {
            onChange: this.onChange.bind(this)
        }
        this.reactComponent.render(reactRoot, props);

    }
    onChange(){
        //Some sort of thing to do with the changes.
        //Hit the API?
        //IDK you decide
    }
    disconnect(){
        const reactRoot = this.targets.find("reactRoot");

        this.reactComponent.destroy(reactRoot);
    }
}

It's pretty simple. But now we can load a react component and enjoy code splitting to not weigh down our app!

What does this look like on the React Side?

The React Code

    import ReactDOM from "react-dom";

    import Something from "./Something";

    function render(node, props){
        ReactDOM.render(node, <Something {...props} />      
    }

    function destroy(node){
        ReactDOM.unmountComponentAtNode(node);
    }

    export {
        render,
        destroy
    }

This is really all there is to it.

Keep in mind as well that React is pretty smart. You can call render with new props from your Stimulus controller and it won't break anything.

The HTML

Finally the html to put it together. It's nothing major

<div data-controller="react-controller">
    <div data-target="react-controller.reactRoot"></div>
</div>

Conclusion

There is a great case for mixing technologies in your applications using the right too where you need it.

You can easily mix React where you need to do some heavy lifting and still keep your app mostly SSR for the rest of your pages with Stimulus.

If you have any questions let me know!

Top comments (3)

Collapse
 
pranavbabu profile image
pranavbabu • Edited

instead of this ReactDOM.render(node, Something);
should be this ReactDOM.render(Something,node); - first comes element you want to render, and second argument is container.

Collapse
 
dnwhte profile image
Dan White

Awesome writeup. Can you explain the purpose of 'await connect()'?

Collapse
 
powerc9000 profile image
Clay Murray

Its just a typo. Thanks for pointing it out