从保存的textarea中反映显示行中断

时间:2016-03-28 10:02:44

标签: javascript reactjs textarea

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

<textarea value={address} />

当我尝试显示地址时,如{address}之类的内容,它没有显示换行符,并且全部在一行上。

<p>{address}</p>

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

6 个答案:

答案 0 :(得分:160)

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

white-space: pre-line;
  

预行

     

空格的序列已折叠。线被破坏了   换行符,位于<br>,并根据需要填充换行符。

查看此演示:

&#13;
&#13;
<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>
&#13;
&#13;
&#13;

browser support for pre-line

答案 1 :(得分:28)

这是预期的,您需要将新行(\ n)字符转换为HTML换行符

关于在反应中使用它的文章:https://medium.com/@kevinsimper/react-newline-to-break-nl2br-a1c240ba746#.l9sbqp5aw

引用文章:

因为您知道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再次是纯函数,两个函数可以彼此相邻。

tldr。溶液

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

现在我们在一个范围内包装每个换行符,这样可以正常工作,因为span的内联显示。现在我们得到了一个有效的nl2br换行解决方案

答案 2 :(得分:5)

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

white-space: pre-line;

答案 3 :(得分:2)

Pete先前关于独立组件的建议是一个很好的解决方案,尽管它忽略了一件重要的事情。列出需求keys。我做了一些调整,我的版本(没有控制台警告)如下:

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

它使用React 16的Fragments

答案 4 :(得分:1)

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

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

你会像这样使用:

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

答案 5 :(得分:0)

喜欢webit版本。我不知道Fragment组件,它是如此有用。无需使用reduce方法。 地图就足够了。另外,list确实需要在react中输入键,但是使用迭代方法中的index却是个坏习惯。 eslint会继续警告我,直到出现混乱错误为止。 所以看起来像这样:

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