web-dev-qa-db-ja.com

React保存されたテキストエリアからの改行を表示

Facebook Reactを使用します。設定ページには、ユーザーが複数行のテキスト(私の場合は住所)を入力できる複数行textareaがあります。

<textarea value={address} />

{address}のようなアドレスを表示しようとすると、改行は表示されず、すべて1行に表示されます。

<p>{address}</p>

これを解決する方法はありますか?

64
denislexic

JSを使用する理由はありません。 white-space CSSプロパティを使用して、改行を処理する方法をブラウザーに簡単に伝えることができます。

white-space: pre-line;

プレライン

空白のシーケンスは折りたたまれています。行は改行文字、<br>、および必要に応じて行ボックスを埋めるために分割されます。

このデモをご覧ください。

<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

181
enapupe

これは予想されることです。改行(\ n)文字をHTML改行に変換する必要があります

反応での使用に関する記事: 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は純粋な関数であり、2つの関数が隣り合う可能性があるため、これも許可されません。

tldr。解決

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

現在、各改行をスパンでラップしていますが、スパンの表示はインラインであるため正常に機能します。これで、有効なnl2br改行ソリューションが得られました。

29
Mark Milford

解決策は、textareaのコンテンツを表示する要素にwhite-spaceプロパティを設定することです。

white-space: pre-line;
6
OualidAj

スタンドアロンコンポーネントに関するPeteの以前の提案は、1つの重要なことを見逃しているものの、優れたソリューションです。リストには keys が必要です。私はそれを少し調整し、私のバージョン(コンソール警告なし)は次のようになります:

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

React 16の Fragments を使用します

2
webit

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>
1
Pete Hodgson

Webitバージョンが大好きです。 Fragmentコンポーネントについては知りませんでした。とても便利です。ただし、reduceメソッドを使用する必要はありません。地図で十分です。また、リストにはreactでキーが必要ですが、反復メソッドのインデックスを使用するのは悪い習慣です。 eslintは、混乱のバグが発生するまで警告でこれを壊し続けました。そのため、次のようになります。

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