128

Suppose I have a text string that contains line-breaks, and I render it like this:

render() {
    var text = "One\nTwo\nThree";
    return <div>{text}</div>;
}

In HTML the line-breaks don't render as line-breaks. How should I do this in React? I don't want to convert to <br> tags and use dangerouslySetInnerHTML. Is there another way?

Aaron Beall
  • 49,769
  • 26
  • 85
  • 103
  • If you used `
    ` that might be the problem. I've noticed the JS Transformer doesn't like it unless you use the `
    ` HTML 4 version.
    – steviesama May 02 '17 at 07:31
  • To assign two lines of React-code to a variable, use parentheses around both lines. () – Vael Victus Nov 28 '17 at 15:05
  • 1
    I fixed this using pre-wrap. Here is my answer to a similar question: https://stackoverflow.com/a/55466235/5346095 – Peter Apr 02 '19 at 02:49

14 Answers14

367

Make a new CSS-class

.display-linebreak {
  white-space: pre-line;
}

Display your text with that CSS-class

render() {
  const text = 'One \n Two \n Three';
  return ( 
     <div className="display-linebreak"> 
        {text} 
     </div>
  );
}

Renders with line-breaks (Sequences of whitespace will collapse into a single whitespace. Text will wrap when necessary). Like this:

One
Two
Three

You may also consider pre-wrap. More info here (CSS white-space Property).

Edgar
  • 6,022
  • 8
  • 33
  • 66
andersvold
  • 3,770
  • 2
  • 10
  • 4
  • 4
    This is a great alternative to the answer I accepted and deserves the upvotes, but I feel I should mention that I tried it and had problems with layout/overflow/rendering; none of the whitespace options seemed to work right in all the cases I needed a fix at the time, while the accepted answer did. – Aaron Beall Oct 25 '17 at 16:28
  • 3
    For sure the best answer. Just add the CSS and no need to use map or anything else. Thanks. – Frederiko Ribeiro Aug 31 '20 at 13:16
88

You could try putting divs for each line

render() {
    return (<div>
        <div>{"One"}</div>
        <div>{"Two"}</div>
        <div>{"Three"}</div>
    </div>);
}

Or

render() {
    var text = "One\nTwo\nThree";
    return (
    <div>
        {text.split("\n").map((i,key) => {
            return <div key={key}>{i}</div>;
        })}
    </div>);
}
stackdave
  • 6,655
  • 9
  • 37
  • 56
Sergio Flores
  • 5,231
  • 5
  • 37
  • 60
  • 5
    I like this. I reckon I could make a `` component out of it, too! – Aaron Beall Feb 11 '16 at 23:35
  • 15
    Why would you use `
    ` to format text lines? `

    ` seems more semantically correct.

    – kost Nov 20 '17 at 22:19
  • 2
    Is this seriously how this *should* be handled? I get that this works, but this creates a mess in the markup. What if the user wants to copy this text? To be fair, the fault here is in react’s handling, not your solution. This may be the best option, but wow. – kevincoleman Dec 17 '19 at 21:59
  • 1
    Don't even think about in react, think in how you can handle this using HTML. The best solution by far is to create the div's, put BR tags or block span's. In my opinion this is the same scenario for HTML/react. – Sergio Flores Dec 18 '19 at 03:56
  • When is `multiline` specifically used? – itiDi Jan 25 '22 at 08:40
36

You could use CSS property "white-space: pre". I think this is the easiest way to handle this.

Brick Yang
  • 5,388
  • 8
  • 34
  • 45
  • Best answer, imo: this is a problem of display, so it should ideally be dealt with in css (not by altering the html) – Bogdan D Jan 20 '17 at 02:03
  • 17
    `white-space:pre` had the same effect as `white-space:nowrap` for me, i.e. the text overflowed its container. Using `white-space:pre-wrap` instead solved this. – rorymorris89 May 21 '17 at 23:10
  • 2
    Only using the "pre" will result in the text exceeding/no wrapping the container. Use `white-space: pre-line;` instead. – Frederiko Ribeiro Aug 31 '20 at 13:18
  • For the subtle different white-space values, check https://developer.mozilla.org/en-US/docs/Web/CSS/white-space – Rodrigo Amaral Nov 22 '21 at 19:25
15

Try this one,

render() {
    var text = "One\nTwo\nThree";
    return <div style={{whiteSpace: 'pre-line'}}>{text}</div>;
}
Codemaker2015
  • 12,190
  • 6
  • 97
  • 81
10

Here the cleanest solution (afaik):

   render(){
      return <pre>
             Line 1{"\n"}
             Line 2{"\n"}
             Line 3{"\n"}
      </pre>
   }

Instead of you can also use <div style={{whiteSpace:"pre"}}>, or any other html block element (like span or p with this style attribute)

Philipp Munin
  • 5,610
  • 7
  • 37
  • 60
  • Thanks after trying out various ways, this is the only solution which worked for me. – Saurabh Rana Feb 27 '20 at 07:39
  • Yes, it's really very simple. Wrap it in a
     tag. `
    {text}
    `, where text could be for example: `const text = "Hello\n\nI need to be formatted in a clean way to please you, Sir\n\nThank you!"`
    – Wu Wei Sep 06 '21 at 16:43
2

You can make use of textarea tag of html, later you can add the styling to the textarea tag. It pretty much solves your all issues including line breaks and tab spaces. Cheerzz...

eg: Your render will look something like below

render() {
    var text = "One\nTwo\nThree";
    return <textarea>{text}</textarea>;
}

Output:

One
Two
Three
Darshuu
  • 501
  • 5
  • 9
1

You can use -webkit-user-modify: read-write-plaintext-only; in your div. It will format and understand things like \n and \p for instance.

Frederiko Ribeiro
  • 1,844
  • 1
  • 18
  • 30
1

You can safely run String.raw instead for this type of value.

const text = String.raw`One
Two
Three
`
render() {
  return <div style={{ whiteSpace: "pre" }}>{text}</div>
}

You can also just use a <pre> tag which effectively does the same thing, but its less semantically clear if you're already using that for other purposes in your app.

trevoro
  • 11
  • 1
1
<div style={{ whiteSpace: "break-spaces" }}> {JSON.stringify(state, null, " ")} </div>
1

We can use package name dedent to render multiline text:

const multilineText = `
  This is line 1
  This is line 2
  This is line 3
`;

export default function App() {
  return (
    <>
      <div style={{ whiteSpace: "pre-wrap" }}>{dedent(multilineText)}</div>
    </>
  );
}
nart
  • 1,508
  • 2
  • 11
  • 24
1

We preferred having <br/>s instead and are using this simple function component in our TypeScript project:

import React, { FunctionComponent } from "react"

export const Multiline: FunctionComponent<{ text: string }> = ({ text }) => (
  <>
    {text.split(/\n|\r\n/).map((segment, index) => (
      <>
        {index > 0 && <br />}
        {segment}
      </>
    ))}
  </>
)
0

Render your delimited text "My line one\nMy second line\nWhatevs..." inside a normal html textarea. I know it works because i just used it today ! Make the textarea readOnly if you must, and style accordingly.

joedotnot
  • 4,810
  • 8
  • 59
  • 91
0

this example in react.js component,

it will insert each line into a new div element by using (map , split) and it is a good example for comments/posts to support ltr/rtl style component at the same time and here is a simple example :

<div> 
    { ' this is first line \n this is second line \n this is third line '.split('\n').map( line => 
    <div  key={ Math.random() * 10} dir="auto"  style={{ textAlign: 'start'}}> {line}  </div> 
    )} 
</div>

also if your string data comming from API / react state you can use your string variable name as the follwing :

<div> 
    { post_comments.split('\n').map( line => 
    <div  key={ Math.random() * 10}  dir="auto"  style={{textAlign: 'start'}}> {line} </div> 
    )} 
</div>

this is just example , and change it based on your case/requirements.

and if you like you can replace div tag with p tag as per your request .

i hope this helpful for you

K.A
  • 1,399
  • 12
  • 24
-1

Open this html page with your browser.

Mine is chromium 115.0.5790.98

#ExampalReactNewLines.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset='UTF-8'>
    <title>ExampalReactNewLines</title>
    <script src='https://unpkg.com/babel-standalone@6.26.0/babel.js'></script>
    <script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
    <script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>

  </head>
  <body>
    <div id='root'></div>
    <script type='text/babel'>
function ExampalReactNewLines() 
{

return (
    
<div>    
{`

1 newline

2 newline

3 newline


7 newline





2 newline


15 newline














stop
`.split(/\n{100}/).map((i,key) => {return <pre key={key}>{i}</pre>;})
}    

</div>
 )
}




















/////////////////////////////////////////////////////////////////////////////////// 
/////////////////////////////////////////////////////////////////////////////////// 
      
      
      
      ReactDOM.render(<ExampalReactNewLines />, document.querySelector('#root'));
    </script>
  </body>
</html> 




quine9997
  • 685
  • 7
  • 13