Peter Dekkers Peter Dekkers - 1 month ago 4
Javascript Question

Add React components from plain JavaScript

Background

I don't have much React experience. I'm writing an embeddable widget using React and Redux. This widget can be included multiple times on the same web page, each with its own settings.

Problem

I'd like to only include the React app JS once. So that if the widget gets included multiple times on a single page it loads the app JS the first time, then for each subsequent include it checks if the JS is already included and if so doesn't again.

So far I'm only able to initialise the first widget instance, which happens when the React app JS is loaded. I'm thinking I'd like to make a lightweight (vanilla JavaScript) call for each subsequent widget that renders a React component with that widget's settings to the DOM.

I can't seem to figure out how to do a plain JavaScript call to make React render a new component.

What it looks like

<script type="text/javascript" src="http://example.com/widget/1"></script>
<script type="text/javascript" src="http://example.com/widget/2"></script>


The first script tag adds a script tag to the page with the main React app JS. It's a big file, ~800 KB. It contains all the React/Redux library inclusions and my React component definitions. It renders a React component and passes it the ID 1.

The second script tag really shouldn't include that file again for the sake of creating a new component on the page. I just want it to render a new React component in the DOM and pass it the ID 2.

Answer

To render a React element, just call:

ReactDOM.render(react_element, dom_element);

Where dom_element is the place you want your react element to go in the page. Relevant docs.

If you want to guard against multiple inclusion of JavaScript, just write your script so that it first checks if it has already run, and then exits immediately if it has. For example:

if (!window.MyWidget) {
  include_scripts();
  window.MyWidget = React.createClass(...)
}
ReactDOM.render(window.MyWidget, this_script_tag);
Comments