19

I have found similar to my issue here.

But I have a little bit different scenario. I have string of html rather than just string. So, I wanted to do:

Let's suppose MyComponent is just returning h3 element for now:

const MyComponent = ({children}) => (<h3>{children}</h3>)

var parts = "<h1>I</h1><p>am a cow;</p>cows say moo. MOOOOO."
    .split(/(\bmoo+\b)/gi);
for (var i = 1; i < parts.length; i += 2) {
  parts[i] = <MyComponent key={i}>{parts[i]}</MyComponent>;
}
// But I need html to be rendered
return <div dangerouslySetInnerHTML={{ __html: parts }} />

This will be rendered in the browser like this:

I
am a cow;
cows say ,[object Object],. ,[object Object],.

What I can think here to resolve the issue is converting component with string of html first.

parts[i] = convertToStringOfHtml(<MyComponent key={i}>{parts[i]}</MyComponent>);

But I don't have idea how to convert component to string of html.

1

3 Answers 3

40

You can do with react-dom

import { renderToString } from 'react-dom/server'
//
//
parts[i] = renderToString(<MyComponent key={i}>{parts[i]}</MyComponent>)

view more here https://reactjs.org/docs/react-dom-server.html

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks. renderToString is what I was looking for. But I need to use parts[i] = renderToString(<MyComponent key={i}>{parts[i]}</MyComponent>); not in __html.
Appreciated your answer. But you may update the answer.
4

You can also do something like this

import React from "react";
import ReactDOM from "react-dom";
import ReactDOMServer from "react-dom/server";


const Hello = () => <div>hello</div>;

const html = ReactDOMServer.renderToStaticMarkup(<Hello />);

console.log(html.toString());

Comments

0

from the docs here: https://react.dev/reference/react-dom/server/renderToString#removing-rendertostring-from-the-client-code


Importing react-dom/server on the client unnecessarily increases your bundle size and should be avoided. If you need to render some component to HTML in the browser, use createRoot and read HTML from the DOM:

import { createRoot } from 'react-dom/client';
import { flushSync } from 'react-dom';

const div = document.createElement('div');
const root = createRoot(div);
flushSync(() => {
  root.render(<MyIcon />);
});
console.log(div.innerHTML); // For example, "<svg>...</svg>"

The flushSync call is necessary so that the DOM is updated before reading its innerHTML property.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.