React display line breaks from saved textarea

JavascriptReactjsTextarea

Javascript Problem Overview


Using Facebook React. In a settings page, I have a multiline textarea where a user can enter multiline text (in my case, an address).

<textarea value={address} />

When I try to display the address, so something like {address}, it doesn't show the line breaks and is all on one line.

<p>{address}</p>

Any ideas how to solve this?

Javascript Solutions


Solution 1 - Javascript

There's no reason to use JS. You can easily tell the browser how to handle newline using the white-space CSS property:

white-space: pre-line;

> pre-line > > Sequences of whitespace are collapsed. Lines are broken at > newline characters, at <br>, and as necessary to fill line boxes.

Check out this demo:

<style>
  #p_wrap {
    white-space: pre-line;
  }
</style>

<textarea id="textarea"></textarea>
<p id="p_standard"></p>
<hr>
<p id="p_wrap"></p>
<script>
  textarea.addEventListener('keypress', function(e) {
    p_standard.textContent = e.target.value
    p_wrap.textContent = e.target.value
  })
</script>

browser support

Solution 2 - Javascript

This is to be expected, you would need to convert the new line (\n) characters to HTML line breaks

An article about using it in react: React Newline to break (nl2br)

To quote article:

> Because you know that everything in React is functions, you can't really do this > > this.state.text.replace(/(?:\r\n|\r|\n)/g, '
') > > Since that would return a string with DOM nodes inside, that is not allowed either, because has to be only a string. > > You then can try do something like this: > > {this.props.section.text.split(“\n”).map(function(item) { > return ( > {item} >
> ) > })}
> > That is not allowed either because again React is pure functions and two functions can be next to each other. > > tldr. Solution > > {this.props.section.text.split(“\n”).map(function(item) { > return ( > > {item} >
>
> ) > })} > > Now we're wrapping each line-break in a span, and that works fine because span’s has display inline. Now we got a working nl2br line-break solution >

Solution 3 - Javascript

The solution is to set the property white-space on the element displaying the content of your textarea:

white-space: pre-line;

Solution 4 - Javascript

Pete's previous proposal with standalone component is great solution although it misses one important thing. Lists needs keys. I adjusted it a bit and my version (without console warnings) looks like this:

const NewLineToBr = ({ children = '' }) => children.split('\n')
  .reduce((arr, line, index) => arr.concat(
    <Fragment key={index}>
      {line}
      <br />
    </Fragment>,
  ), [])

It uses React 16's Fragments

Solution 5 - Javascript

As of React 16 a component can return an array of elements, which means you can create a component like this:

export default function NewLineToBr({children = ""}){
  return children.split('\n').reduce(function (arr,line) {
    return arr.concat(
      line,
      <br />
    );
  },[]);
}

which you'd use like this:

<p>
  <NewLineToBr>{address}</NewLineToBr>
</p>

Solution 6 - Javascript

A small addition to answers above: white-space property should better be used with word-wrap to prevent overflowing.

p {
  white-space: pre-wrap;
  word-wrap: break-word;   
}

Solution 7 - Javascript

Love webit version. I did not know about the Fragment component, it is so useful. No need to use the reduce method though. Map is enough. Also, list do need keys in react , but it is bad habit to use index from the iterating method for it. eslint kept on smashing this in my warning until I had the confusion bug. So it'd look like this :

const NewLine = ({ children }) =>
   children.split("\n").map(line => (
    <Fragment key={uuidv4()}>
      {line}
      <br />
    </Fragment>
  ));

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestiondenislexicView Question on Stackoverflow
Solution 1 - JavascriptenapupeView Answer on Stackoverflow
Solution 2 - JavascriptMark MilfordView Answer on Stackoverflow
Solution 3 - JavascriptOualidAjView Answer on Stackoverflow
Solution 4 - JavascriptwebitView Answer on Stackoverflow
Solution 5 - JavascriptPete HodgsonView Answer on Stackoverflow
Solution 6 - JavascriptAbdulhakimView Answer on Stackoverflow
Solution 7 - JavascriptHandleView Answer on Stackoverflow