Unfortunately, I don’t think there’s a way to achieve this without doing something a little unorthodox (read: hacky).
TLDR: Here’s a sandbox with what I think is a viable solution for you.
Continuing on, there are a couple of problems preventing your code from working.
When you define reactHTML
you’re not actually defining HTML but rather a react Element
Object (because that’s what JSX compiles it into).
This means that you won’t be able to use DOM selectors on it (e.g. querySelector
and appendChild
) and that is why you get the error appendChild does not exist on type 'Element'
. This makes sense because the react Element
object does not have such a method.
The “solution” then, is to render your markdown content as you normally would, and only after being rendered go in and access the elements that you want. This can be easily achieved with the useEffect
hook very similar to what you’re already doing:
const Markdown = (props) => {
const markdown = `
This is rendered as a '<p>' element
So is this one!
Me too!
`;
useEffect(() => {
// Get all of the <p> elements
const pElements = document.getElementsByTagName("p");
// Create a button
const button = document.createElement("button");
button.id = "btn-1";
button.innerHTML = "I'm a button!";
const refChild = pElements[1];
// Insert the button before the next sibling of the second <p> tag
refChild && refChild.parentNode.insertBefore(button, refChild.nextSibling);
}, []);
return <ReactMarkdown children={markdown} />;
};