【问题标题】:React display line breaks from saved textarea从保存的文本区域反应显示换行符
【发布时间】:2016-07-15 13:47:54
【问题描述】:

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

<textarea value={address} />

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

<p>{address}</p>

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

【问题讨论】:

    标签: javascript reactjs textarea


    【解决方案1】:

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

    white-space: pre-line;
    

    上线前

    空格序列被折叠。线条在 换行符,&lt;br&gt;,并根据需要填充行框。

    看看这个演示:

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

    【讨论】:

    • 这有多种工作方式:如果您尝试通过变量在 JSX 中呈现换行符 (
      ),它将“安全地”呈现标记而不是添加换行符。在此 CSS 中使用转义字符可以解决该安全机制并解决所述问题。
    • 非常好的和简单的解决方案。现在所有换行符都可以按预期对 texarea 工作。
    • 这是我想多次投票的答案之一。非常感谢@enanupe
    【解决方案2】:

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

    一篇关于在react中使用它的文章:React Newline to break (nl2br)

    引用文章:

    因为你知道 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 中,这可以正常工作,因为 span 具有内联显示。现在我们得到了一个有效的 nl2br 换行解决方案

    【讨论】:

    • 谢谢马克,就像一个魅力。你有机会把答案放在这里吗? Stackoverflow 不喜欢外部链接(可能会消失,更难查看答案列表,...),我会将您的答案标记为正确。
    • 其他人注意:您还需要在span中添加一个key属性,因为它处于循环中。所以应该是....map(function (item, i) { return &lt;span key={i}&gt;{item}&lt;br/&gt;&lt;/span&gt; })
    • 很好的答案!这对我很有帮助。另外,如果您有多个换行符,您可以防止多余的&lt;br /&gt; 呈现最后一项:....map(function (item, i, arr) { return &lt;span key={i}&gt;{item}{ arr.length-1 === i ? null : &lt;br/&gt;}&lt;/span&gt; })。请注意,我包含了 .map() 的第三个参数
    • 我不明白你是如何做到这一点的。我在
    • @Ed。它是显示不在文本区域中的 HTML 文本。这有帮助吗?
    【解决方案3】:

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

    white-space: pre-line;
    

    【讨论】:

      【解决方案4】:

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

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

      它使用 React 16 的 Fragments

      【讨论】:

      • 索引作为键只有在您确定映射数据是“静态”并且在其生命周期中永远不会改变时才是安全的,否则您可能会遇到问题。
      【解决方案5】:

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

      【讨论】:

      • 我不得不将 '\n' 更改为 '\\n'。
      【解决方案6】:

      对上述答案的一个小补充: white-space 属性最好与word-wrap 一起使用,以防止溢出。

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

      【讨论】:

        【解决方案7】:

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

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

        【讨论】:

        • 在 React 中使用 uuid 作为 key 是个坏主意,因为每个新的渲染都会认为这个元素是新的,从而适应 DOM。
        猜你喜欢
        • 1970-01-01
        • 2018-06-14
        • 1970-01-01
        • 2017-03-17
        • 2013-03-01
        • 2010-12-01
        • 1970-01-01
        相关资源
        最近更新 更多