It is simple to embed React Js components into pure HTML files.
- Add a DOM container to the HTML document to mount your React Js component
- Add the React Js script tags to load React from the CDN
- Write the React Js component.
I have this simple HTML file to log my monthly expenses. I know all the unit costs, but it would be nice to know the amounts due with taxes.
What I want is a simple calculator widget under the expenses table.
That is a good candidate for a React Js component. Let's take a look at what it takes to implement a simple calculator widget in React.
Here is the existing HTML that I use to enter expenses.
<html>
<body>
<table>
<tr>
<th>Product</th>
<th>Unit Price</th>
<th>Total</th>
</tr>
<tr>
<td>Auto Insurance</td>
<td>$76.90</td>
<td><input/></td>
</tr>
<tr>
<td>Home Insurance</td>
<td>$227.98</td>
<td><input/></td>
</tr>
<tr>
<td>Electricity</td>
<td>$79.97</td>
<td><input/></td>
</tr>
<tr>
<td>Natural Gas</td>
<td>$67.57</td>
<td><input/></td>
</tr>
<tr>
<td>Water</td>
<td>$51.35</td>
<td><input/></td>
</tr>
</table>
<!-- I want a tax calculator here -->
</body>
</html>
1. Add a DOM container to mount the React Js component
Embedding React in HTML differs slightly from what we have done with React Js. In a standard React Js app, the root element in the index.html is the container that mounts the React Js app. I need something similar to mount my tax widget in the HTML file.
<div id="tax_widget_root"></div>
2. Add React Js script tags
I run a React app in an HTML file. No node_modules to provide React Js dependencies. Therefore, I must add React dependencies by including React script tags in the HTML document. That is similar to adding JQuery dependency into an HTML document.
<script src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
My React Js component returns JSX. Therefore I also need Babel to transform that JSX. (not suitable in production environments. See conclusion)
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
3. Write React Js code in HTML
My React Js code is enclosed within the text/babel script tag because Babel knows how to transpile JSX code.
<script type="text/babel">
const TaxCalculator = () => {
const [price, setPrice] = React.useState()
const [tax, setTax] = React.useState()
const resetCalculator = () => {
setPrice("")
setTax("")
}
let total = 0;
if(!!price && !! tax){
total = (Number(price) * (100 + Number(tax)) / 100).toFixed(2)
}
return <table>
<tr>
<th>Simple Tax Calculator</th>
</tr>
<tr>
<td><input type="number"
value={price}
onChange={(e) => setPrice(e.target.value)}
placeholder="unit price"/>
</td>
</tr>
<tr>
<td><input type="number"
value={tax}
onChange={(e) => setTax(e.target.value)}
placeholder="tax perentage"/>
</td>
</tr>
<tr>
<td>Total: {total}<button onClick={resetCalculator} style={{float:"right"}}>Reset</button></td>
</tr>
</table>
}
const container = document.getElementById('tax_widget_root');
const root = ReactDOM.createRoot(container);
root.render(<TaxCalculator />);
</script>
The complete code with a React Js tax calculator is embedded in a pure HTML file. I have added some CSS to make it pretty. I can double-click the HTML file to open it, and React Js works out of the box.
<html>
<style>
#expenses {
font-family: Arial, Helvetica, sans-serif;
border-collapse: collapse;
width: 50%;
}
#expenses td, #expenses th {
border: 1px solid #ddd;
padding: 8px;
}
#expenses th {
padding-top: 12px;
padding-bottom: 12px;
text-align: left;
background-color: Blue;
color: white;
}
</style>
</head>
<body>
<table id="expenses">
<tr>
<th>Product</th>
<th>Unit Price</th>
<th>Total</th>
</tr>
<tr>
<td>Auto Insurance</td>
<td>$76.90</td>
<td><input/></td>
</tr>
<tr>
<td>Home Insurance</td>
<td>$227.98</td>
<td><input/></td>
</tr>
<tr>
<td>Electricity</td>
<td>$79.97</td>
<td><input/></td>
</tr>
<tr>
<td>Natural Gas</td>
<td>$67.57</td>
<td><input/></td>
</tr>
<tr>
<td>Water</td>
<td>$51.35</td>
<td><input/></td>
</tr>
</table>
<br/>
<div id="tax_widget_root"></div>
<script type="text/babel">
const TaxCalculator = () => {
const [price, setPrice] = React.useState()
const [tax, setTax] = React.useState()
const resetCalculator = () => {
setPrice("")
setTax("")
}
let total = 0;
if(!!price && !! tax){
total = (Number(price) * (100 + Number(tax)) / 100).toFixed(2)
}
return <table id="expenses" style={{width:"16%"}}>
<tr>
<th style={{backgroundColor: "green"}}>Simple Tax Calculator</th>
</tr>
<tr>
<td>
<input type="number"
value={price} onChange={(e) => setPrice(e.target.value)}
placeholder="unit price"/>
</td>
</tr>
<tr>
<td>
<input type="number"
value={tax} onChange={(e) => setTax(e.target.value)}
placeholder="tax perentage"/>
</td>
</tr>
<tr>
<td>Total: {total}
<button onClick={resetCalculator} style={{float:"right"}}>Reset</button>
</td>
</tr>
</table>
}
const container = document.getElementById('tax_widget_root');
const root = ReactDOM.createRoot(container);
root.render(<TaxCalculator />);
</script>
<!-- Load our React component. -->
<script src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</body>
</html>
Conclusion
Embedding React Js in HTML is ok for non-production and prototyping projects. It usually slows down page loads and degrades performance. Consider adding the JSX pre-processor to convert script tags to JSX automatically for production environments.