Newline in react string [Solved]

If you’ve ever wondered how to render the newline character (\n) in a string as an actual newline in your React app, read on.

Imagine you have the following boilerplate code:

import * as React from 'react';
import * as ReactDOM from 'react-dom';

ReactDOM.render(
  <div className="App">
    
  </div>,
  document.getElementById('root')
);

You have a simple component and that you want to pass the following prop:

text: 'Line one\nLine two'

And want the output to be:

Line one
Line two

Turns out you have a couple of options: You could render each new line as a paragraph, or you could use the CSS white-space property.

Render each new line as a paragraph

This method involves splitting the text with the .split() method, then wrapping each new string in a paragraph element.

First, create a simple component:

import * as React from 'react';
import * as ReactDOM from 'react-dom';

function NewlineText(props) {
  
}

ReactDOM.render(
  <div className="App">
    <NewlineText />
  </div>,
  document.getElementById('root')
);

Next, pass the component the string 'Line one\nLine two\nLine three' as the prop text. Note that you’ll need to wrap the string in bracket ({}) so the newline characters are not interpreted as plain text:

import * as React from 'react';
import * as ReactDOM from 'react-dom';

function NewlineText(props) {
  
}

ReactDOM.render(
  <div className="App">
    <NewlineText text={'Line one\nLine two\nLine three'} />
  </div>,
  document.getElementById('root')
);

Next, declare a variable named text and set it equal to props.text:

function NewlineText(props) {
  const text = props.text;
  
}

Now you need to use the .split() method split the text string on each newline character and create an array of strings:

function NewlineText(props) {
  const text = props.text;
  const newText = text.split('\n');
  
}

Then, use the .map() method to iterate through the array of strings and return each as a paragraph element:

function NewlineText(props) {
  const text = props.text;
  const newText = text.split('\n').map(str => <p>{str}</p>);
  
}

Finally, return newText from the component:

function NewlineText(props) {
  const text = props.text;
  const newText = text.split('\n').map(str => <p>{str}</p>);
  
  return newText;
}

And the original text will be rendered like so:

This works because paragraph elements are block level elements by default (display: block;). Browsers render each block level element on a new line.

However, this does also add some default upper and lower margins to each paragraph element. You can use CSS to remove the margins if you wish.

For bonus points, you could make your code a bit more succinct. For example:

import * as React from 'react';
import * as ReactDOM from 'react-dom';

function NewlineText(props) {
  const text = props.text;
  return text.split('\n').map(str => <p>{str}</p>);
}

ReactDOM.render(
  <div className="App">
    <NewlineText text={'Line one\nLine two\nLine three'} />
  </div>,
  document.getElementById('root')
);

Use the CSS white-space property

This method involves using the white-space property to preserve the newline characters in the original string.

First, create a simple component and pass it 'Line one\nLine two\nLine three' as the prop text:

import * as React from 'react';
import * as ReactDOM from 'react-dom';

function NewlineText(props) {
  
}

ReactDOM.render(
  <div className="App">
    <NewlineText text={'Line one\nLine two\nLine three'} />
  </div>,
  document.getElementById('root')
);

Next, declare a variable named text and set it equal to props.text:

function NewlineText(props) {
  const text = props.text;
  
}

Then, just wrap text in a div element and return it:

function NewlineText(props) {
  const text = props.text;
  return <div>{text}</div>;
}

Finally in your CSS file, target the div element and set the white-space property to pre-wrap:

div {
  white-space: pre-wrap;
}

The value pre-wrap preserves all white space characters, including line breaks with newline characters and <br>.

Now your code should look like this:

import * as React from 'react';
import * as ReactDOM from 'react-dom';

function NewlineText(props) {
  const text = props.text;
  return <div>{text}</div>;
}

ReactDOM.render(
  <div className="App">
    <NewlineText text={'Line one\nLine two\nLine three'} />
  </div>,
  document.getElementById('root')
);

Which results in the following output:

Wrapping up

These are just two ways to render newlines in React strings. Here’s a Repl.it snippet with both methods side-by-side:

Now go forth and render all the new lines.

2 Likes

To use <br> you have to use dangerouslySetInnerHTML

1 Like

Heard that it is ‘dangerous’ to use it! :smiley:

Yeah :smiley: if your string can have html tag you should “validate” it

Also, you tried setting the tag in your stylesheet to display:block? Or using flex box to create a column?

Well I fixed this with:

let newText = text.split('\n').map((item, i) => {
    return <p key={i}>{item}</p>;
});
1 Like

Sorry, I don’t understand what you mean.

Why try creating a new line in JavaScript when you’re essentially storing an array of <p> tags? It would make more sense to me to change the way the elements are positioned on the page.

Because I have a text which changes when the state changes. That means that I have different lines depending on the state.
I am using <p> tags, to make that line break.

Hope it makes sense. :stuck_out_tongue:

Only a little advice with ES6, if you have to return a function ( <tag></tag> babel transform it in a single function ) you can write in this way:

let newText = text.split ('\n').map ((item, i) => <p key={i}>{item}</p>);

Maybe you already know it, but for future generations could be useful :grin:

1 Like

Yeah, good piece of advice! :slight_smile:

I see you marked this solved, but in case someone visits this later:

If you are adding multiple lines of text with \n to a div, add the following to the css for the div in question:

div {
  white-space: pre-wrap;
} 

Simple example

18 Likes

Thank you, very interesting!

Thanks! I spant few hours before to find this solution and it’s perfectly work for me!

Thanks a lot! this is the neatest solution i found around web :slight_smile:

“pre-wrap” non-support ie and edge.

another little advice, react automatically uses the index as a key if no other key is provided so key={i} is redundant :slight_smile:

I used the following

const addLineBreaks = string =>
  string.split('\n').map((text, index) => (
    <React.Fragment key={`${text}-${index}`}>
      {text}
      <br />
    </React.Fragment>
  ));

<h1>{addLineBreaks(heading)}</h1>
2 Likes

This worked for me too! Super helpful!

Came here 4 years later to find out this is the answer to my problem, as you predicted. Thank you for posting.