skip to Main Content

I have strings stored in a DB that are partial HTML, for example:

“Intro<br /><br />Paragraph 1<br /><br />Paragraph 2”

Say I want to render this string within a new <p> element, what is a simple way to accomplish this?

I am looking for a solution that doesn’t use an additional package and instead uses native JavaScript or a non-deprecated React function.

I am serving these string snippets to the React client, and I want React to eventually convert them from strings to HTML elements. However, doing so using document.createElement and manipulating the innerHTML of this new element gives me an error saying that Objects cannot be rendered in React. Say this new element is called elem, I am trying to render is like so:
render(<div>{elem}</div>)

2

Answers


  1. You can render it through this method:

    // Assuming you have the string stored in a variable named `htmlString`
    const htmlString = "Intro<br /><br />Paragraph 1<br /><br />Paragraph 2";
    
    // Create a new <p> element
    const paragraph = document.createElement('p');
    
    // Set the innerHTML of the <p> element to the HTML string
    paragraph.innerHTML = htmlString;
    
    // Now `paragraph` contains the parsed HTML content
    // You can append it to the DOM wherever you want
    document.body.appendChild(paragraph);
    

    Another way in React

    import React from 'react';
    
    const YourComponent = () => {
      // Assuming you have the string stored in a variable named `htmlString`
      const htmlString = "Intro<br /><br />Paragraph 1<br /><br />Paragraph 2";
    
      return (
        <div>
          {/* 
            Using dangerouslySetInnerHTML to set the HTML content 
            Make sure the HTML content is safe and trusted 
          */}
          <p dangerouslySetInnerHTML={{ __html: htmlString }}></p>
        </div>
      );
    }
    
    export default YourComponent;
    
    Login or Signup to reply.
  2. The issue is that the string “Intro<br /><br />Paragraph 1<br /><br />Paragraph 2” is a string. It is not JSX. It does not get transposed into function calls for React elements. So that string will simply be output to the DOM as a string, and that string will appear as text in the browser.

    React uses a transpiling process to convert the JSX in your source code into JS function calls. It does that during build-time. The string in your database is not fetched until run-time, so there’s no opportunity for the React build process to transpile it.

    Lots of people have done things to "make this work" at runtime, but mostly those solutions are clunky and/or extremely dangerous, security-wise.

    For example: Programmatically generated JSX string

    IMO the better approach would be for you to build some type of parser and/or simple Domain Specific Language (DSL) so that in your React code you are getting the data from the database, "interpreting" it, and dynamically rendering JSX.

    For example, the above string could be processed as:

    const MyParserThingy = (props) => {
    
        const stringParts = props.inputString.split('<br />');
        let colorCounter = 0;
    
        return (<div>
            {stringParts.map((part) => {
               if(part.length > 0) {
                 const theColor = (colorCounter++ % 2 === 0) ? 'red' : 'blue';
                 return <p style={{color: theColor}}>{part}</p>;
               } else {
                 return null;
               }
             })}
          </div>
        );
    };
    
    ReactDOM.createRoot(
      document.getElementById("root")
    ).render( <MyParserThingy inputString="Intro<br /><br />Paragraph 1<br /><br />Paragraph 2" />);
    <div id="root"></div>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.0.0/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.0.0/umd/react-dom.production.min.js"></script>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search