152

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?

3
  • If you used <br> that might be the problem. I've noticed the JS Transformer doesn't like it unless you use the <br/> HTML 4 version. Commented May 2, 2017 at 7:31
  • To assign two lines of React-code to a variable, use parentheses around both lines. () Commented Nov 28, 2017 at 15:05
  • 1
    I fixed this using pre-wrap. Here is my answer to a similar question: stackoverflow.com/a/55466235/5346095 Commented Apr 2, 2019 at 2:49

13 Answers 13

416

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).

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

2 Comments

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.
For sure the best answer. Just add the CSS and no need to use map or anything else. Thanks.
94

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>);
}

5 Comments

I like this. I reckon I could make a <MultilineText> component out of it, too!
Why would you use <div> to format text lines? <p> seems more semantically correct.
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.
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.
When is multiline specifically used?
41

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

4 Comments

Best answer, imo: this is a problem of display, so it should ideally be dealt with in css (not by altering the html)
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.
Only using the "pre" will result in the text exceeding/no wrapping the container. Use white-space: pre-line; instead.
For the subtle different white-space values, check developer.mozilla.org/en-US/docs/Web/CSS/white-space
21

Try this one,

render() {
    var text = "One\nTwo\nThree";
    return <div style={{whiteSpace: 'pre-line'}}>{text}</div>;
}

Comments

11

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)

2 Comments

Thanks after trying out various ways, this is the only solution which worked for me.
Yes, it's really very simple. Wrap it in a <pre> tag. <pre>{text}</pre>, 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!"
5

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>
    </>
  );
}

Comments

4

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}
      </>
    ))}
  </>
)

Comments

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

Comments

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.

Comments

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.

Comments

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

Comments

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.

Comments

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.