'Formatting code with <pre> tag in React and JSX

I am trying to use the pre tag inside of JSX.When you use the pre tag in JSX, it doesn't format at all. Why? In order to use the pre tag I need to do something like this:

const someCodeIWantToFormat = "var foo = 1"
const preBlock = { __html: "<pre>" + pythonCode + "</pre>" };
return(
  <div dangerouslySetInnerHTML={ preBlock } />;
)

Why?



Solution 1:[1]

Use template literals

Template literals allow the use of multi-line strings which preserve leading/trailing white-space and new lines.

const pythonCode = `
    print(
        "Hello, World!"
    )
`

class PreFormattedCode extends React.Component {
    render() {
      return <React.Fragment>{pythonCode}</React.Fragment>
    }
}

ReactDOM.render(<PreFormattedCode />, document.getElementById('code'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

<!-- The content rendered into this tag will preserve whitespace -->
<pre id="code"></pre>

Solution 2:[2]

Gfullam has a posted a great answer.

I'll expand it a bit and provide some alternative solutions. Most of these are probably overkill for your particular case. However I believe you (and potential future readers) might find these useful. Note that these require ES6.


Template Literal Expression

Since you already have your code stored in a variable, you could use a Template Literal Expression. This is might be preferable if you have many variables or if you want to control your output.

class SomeComponent extends React.Component {
   render() {
     var foo = 1;
     var bar = '"a b   c"';
        return (
          <pre>{`
            var foo = ${foo};
            var bar = ${bar};
          `}</pre>
        )
    }
}

ReactDOM.render(
  <SomeComponent />, 
  document.getElementById('content')
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="content"></div>

Perhaps not needed in this particular implementation, but it might be good to know that also can do function calls and other operations within the brackets.

CodePen


Tagged Template Literals

If you don't want to manually add line-breaks, semi-colons and other code formatting for your <pre> tag, you could use a Tagged Template Literal to return the right output for you. Just provide it with the variables to output!

class SomeComponent extends React.Component {
  pre(strings, variables) {
    return variables.map((v, i) => {
      return `var ${v.name} = ${v.value};
`
    })
  } 
  
  render() {
     var variables = [{name: "foo", value: 1},{name: "bar", value: '"a b   c"'}];
     return <pre>{this.pre`${variables}`}</pre>;
    }
}

ReactDOM.render(
  <SomeComponent />, 
  document.getElementById('content')
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="content"></div>

PS: Isn't this awesome!?

CodePen

Solution 3:[3]

A good way to format in jsx is to use String.raw with a template literal and then the pre tag in your jsx. This helps eliminate any escape issues if you're doing something like this.

I did this for a starwars api project in React. This was my header.

    const Header = () => {

        var title = String.raw`
             ___| |_  ___  _____ __      _  ___  _____ ___
            / __| __|/ _  |  __/ \ \ /\ / // _  |  __// __|
            \__ | |_  (_| | |     \ V  V /  (_| | |   \__ |
            |___/\__|\__,_|_|      \_/\_/  \__,_|_|   |___/
        `;
        return (
            <div>
                <pre> {title} </pre>
            </div>
        )
    };

    export default Header;

Solution 4:[4]

use

<pre>
  {JSON.stringify(yourdataobject, null, 2)}
</pre>

to render objects

Solution 5:[5]

Try this

    <Row key={i} className="question">
      <Col xs="12" className="article" >
        Article {article + 1})
      </Col>
      <Col xs="12">
        <pre>{`${v.QuestionDesc}`}</pre>
      </Col>
   </Row>

Hope for help.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Community
Solution 3 bobbyrne01
Solution 4 Andris Laduzans
Solution 5 superup