Javascript 从保存的文本区域反应显示换行符

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/36260013/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 18:50:08  来源:igfitidea点击:

React display line breaks from saved textarea

javascriptreactjstextarea

提问by denislexic

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

使用脸书React。在设置页面中,我有一个多行textarea,用户可以在其中输入多行文本(在我的例子中是地址)。

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

当我尝试显示地址时,例如{address},它不显示换行符并且全部在一行上。

<p>{address}</p>

Any ideas how to solve this?

任何想法如何解决这个问题?

回答by enapupe

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

没有理由使用JS。您可以使用white-spaceCSS 属性轻松告诉浏览器如何处理换行符:

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.

前线

空白序列被折叠。换行符、 at<br>和必要时换行以填充行框。

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 for pre-line

浏览器对前线的支持

回答by Mark Milford

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

这是意料之中的,您需要将新行 (\n) 字符转换为 HTML 换行符

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

一篇关于在 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, '<br />')

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

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 (
    <span>
      {item}
      <br/>
    </span>
  )
})}

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

因为你知道 React 中的一切都是函数,所以你不能真正做到这一点

this.state.text.replace(/(?:\r\n|\r|\n)/g, '<br />')

由于这将返回一个包含 DOM 节点的字符串,这也是不允许的,因为它只能是一个字符串。

然后你可以尝试做这样的事情:

{this.props.section.text.split(“\n”).map(function(item) {
  return (
    {item}
    <br/>
  )
})}    

这也是不允许的,因为 React 又是纯函数,两个函数可以相邻。

域名 解决方案

{this.props.section.text.split(“\n”).map(function(item) {
  return (
    <span>
      {item}
      <br/>
    </span>
  )
})}

现在我们将每个换行符包装在一个跨度中,这很好用,因为跨度具有内联显示。现在我们得到了一个有效的 nl2br 换行解决方案

回答by OualidAj

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

解决方案是white-space在显示您的内容的元素上设置属性textarea

white-space: pre-line;

回答by webit

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:

Pete 之前提出的带有独立组件的提议是很好的解决方案,尽管它遗漏了一件重要的事情。列表需要。我稍微调整了一下,我的版本(没有控制台警告)看起来像这样:

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

It uses React 16's Fragments

它使用 React 16 的Fragments

回答by Pete Hodgson

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

从 React 16 开始,一个组件可以返回一个元素数组,这意味着你可以像这样创建一个组件:

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>

回答by Handle

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 :

喜欢网络版。我不知道 Fragment 组件,它是如此有用。不过不需要使用reduce方法。地图就够了。此外, list 确实需要 react 中的键,但使用迭代方法中的 index 是坏习惯。eslint 一直在我的警告中粉碎它,直到我遇到混淆错误。所以它看起来像这样:

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