Convert HTML to React components using recursion

Do you need to transform an HTML string into React components, but don't want to do it manually?

There are several handy libraries that can automate this for you:

But maybe you have a more custom use case, or you're just curious how it's done.

Here's how you can do it yourself with a simple recursive function.

Setup

We'll use a couple of dependencies to make things easier:

yarn add himalaya html-attribute-to-react --save

Code

// convertToComponents.js

import React from 'react';
import { parse } from 'himalaya';
import htmlAttributeToReact from 'html-attribute-to-react';

function buildComponentTree(nodes) {
return nodes.map((node, i) => {
switch (node.type) {
case 'text':
// Node is just a string, so return it as is
return node.content;

case 'element':
// Recursively get nodes for element's children
const children = buildComponentTree(node.children);

// Convert element's attributes to React props
const attrs = node.attributes.reduce(
(acc, attr) => ({
...acc,
[htmlAttributeToReact(attr.key)]: attr.value,
}),
{}
);

// Create React element
return React.createElement(
node.tagName,
{ ...attrs, key: `${node.type}-${i}` },
children.length ? children : null
);

default:
// Return null for any non-text/element nodes
return null;
}
});
}

export default function convertToComponents(html) {
return buildComponentTree(parse(html));
}

Then you can import this module into your component files, and use it like this:

// SomeComponent.js

import React from 'react';
import convertToComponents from './convertToComponents';

const SomeComponent = () => {
return (
<div>
{convertToComponents(
'<p>I will be transformed into React!</p>'
)}
</div>
)
}

export default SomeComponent;

Succeed in tech

Get actionable tips on coding, getting hired and working as a developer.

I won't spam you. Unsubscribe any time.