Как отрендерить многострочную текстовую строку в React

87

Предположим, у меня есть текстовая строка, содержащая разрывы строк, и я визуализирую ее так:

render() {
    var text = "One\nTwo\nThree";
    return <div>{text}</div>;
}

В HTML разрывы строк не отображаются как разрывы строк. Как мне это сделать в React? Я не хочу конвертировать в <br>теги и использовать dangerouslySetInnerHTML. Есть другой способ?

Аарон Билл
источник
Если вы использовали, <br>это могло быть проблемой. Я заметил, что JS Transformer не нравится, если вы не используете <br/>версию HTML 4.
steviesama
Чтобы присвоить переменной две строки кода React, заключите обе строки в круглые скобки. ()
Vael Victus
1
Я исправил это с помощью предварительной упаковки. Вот мой ответ на аналогичный вопрос: stackoverflow.com/a/55466235/5346095
JS dev

Ответы:

73

Вы можете попробовать разместить div для каждой строки

render() {
    return (<div>
        <div>{"One"}</div>
        <div>{"Two"}</div>
        <div>{"Three"}</div>
    </div>);
}

Или же

render() {
    var text = "One\nTwo\nThree";
    return (
    <div>
        {text.split("\n").map((i,key) => {
            return <div key={key}>{i}</div>;
        })}
    </div>);
}
Серхио Флорес
источник
5
Мне это нравится. Думаю, я тоже мог бы сделать из него <MultilineText>компонент!
Аарон Билл,
13
Зачем вам <div>форматировать текстовые строки? <p>кажется более семантически правильным.
Кость
1
Является ли это серьезно , как это должно быть обработано? Я понимаю, что это работает, но это создает беспорядок в разметке. Что, если пользователь захочет скопировать этот текст? Честно говоря, ошибка здесь в обработке реакции, а не в вашем решении. Это может быть лучший вариант, но ничего себе.
kevincoleman
1
Даже не думайте о реакции, подумайте, как с этим справиться с помощью HTML. Лучшим решением на сегодняшний день является создание div, размещение тегов BR или диапазона блоков. На мой взгляд, это тот же сценарий для HTML / react.
Серхио Флорес
245

Создайте новый CSS-класс

.display-linebreak {
  white-space: pre-line;
}

Отобразите свой текст с помощью этого CSS-класса

render() {
  const text = 'One \n Two \n Three';
  return ( 
     <div className="display-linebreak"> 
        {text} 
     </div>
  );
}

Визуализирует с переносом строки (последовательности пробелов превращаются в один пробел. Текст при необходимости переносится). Как это:

One
Two
Three

Вы также можете рассмотреть возможность предварительной упаковки. Подробнее здесь ( свойство CSS white-space ).

Андерсвольд
источник
2
Это отличная альтернатива ответу, который я принял, и он заслуживает положительных отзывов, но я чувствую, что должен упомянуть, что пробовал его и имел проблемы с макетом / переполнением / рендерингом; ни один из вариантов пробелов, похоже, не работал правильно во всех случаях, когда мне нужно было исправить в то время, в то время как принятый ответ работал.
Аарон Билл
1
Наверняка лучший ответ. Просто добавьте CSS и не нужно использовать карту или что-то еще. Благодарю.
Фредерико Сезар
26

Вы можете использовать свойство CSS «white-space: pre». Думаю, это самый простой способ справиться с этим.

Кирпич Ян
источник
Лучший ответ, imo: это проблема отображения, поэтому в идеале ее следует решать в css (а не путем изменения html)
Bogdan D
12
white-space:preимел тот же эффект, что и white-space:nowrapу меня, т.е. текст вышел за пределы своего контейнера. Использование white-space:pre-wrapвместо этого решило эту проблему.
rorymorris89
Только использование «pre» приведет к тому, что текст будет превышать / не обертывать контейнер. white-space: pre-line;Вместо этого используйте .
Фредерико Сезар
6

Вот самое чистое решение (афаик):

   render(){
      return <pre>
             Line 1{"\n"}
             Line 2{"\n"}
             Line 3{"\n"}
      </pre>
   }

Вместо этого вы также можете использовать <div style={{whiteSpace:"pre"}}>любой другой элемент блока html (например, spanили pс этим атрибутом стиля)

Филипп Мунин
источник
Спасибо, попробовав разные способы, это единственное решение, которое сработало для меня.
Саураб Рана
2

Попробуй это,

render() {
    var text = "One\nTwo\nThree";
    return <div style={{whiteSpace: 'pre-line'}}>{text}</div>;
}
Codemaker
источник
0

Визуализируйте текст с разделителями «Моя первая строка \ nМоя вторая строка \ nWhatevs ...» внутри обычного текстового поля html. Я знаю, что это работает, потому что использовал его только сегодня! Сделайте textarea доступным только для чтения, если необходимо, и задайте соответствующий стиль.

Joedotnot
источник
0

Вы можете использовать -webkit-user-modify: read-write-plaintext-only;в своем div. Например, он будет форматировать и понимать такие вещи, как \ n и \ p.

Фредерико Сезар
источник
0

Вы можете использовать тег textarea HTML, позже вы можете добавить стиль к тегу textarea. Это в значительной степени решает все ваши проблемы, включая разрывы строк и пробелы. Cheerzz ...

например: ваш рендер будет выглядеть примерно так, как показано ниже

render() {
    var text = "One\nTwo\nThree";
    return <textarea>{text}</textarea>;
}

Вывод:

One
Two
Three
Даршуу
источник
0

String.rawВместо этого вы можете безопасно работать с этим типом значения.

const text = String.raw`One
Two
Three
`
render() {
  return <div style={{ whiteSpace: "pre" }}>{text}</div>
}

Вы также можете просто использовать <pre>тег, который фактически делает то же самое, но его семантически менее понятно, если вы уже используете его для других целей в своем приложении.

Треворо
источник
0
<div style={{ whiteSpace: "break-spaces" }}> {JSON.stringify(state, null, " ")} </div>
Адам Рыбински
источник