Using React with Stimulus JS

Saturday, June 22, 2019

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!

This post is also available on DEV.