Jak wyrenderować wielowierszowy ciąg tekstowy w React

87

Załóżmy, że mam ciąg tekstowy zawierający znaki końca wiersza i renderuję go w następujący sposób:

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

W HTML znaki końca linii nie są renderowane jako znaki końca linii. Jak mam to zrobić w React? Nie chcę konwertować na <br>tagi i używać dangerouslySetInnerHTML. Czy jest inny sposób?

Aaron Beall
źródło
Jeśli używałeś <br>, może to być problem. Zauważyłem, że JS Transformer nie lubi tego, chyba że używasz wersji <br/>HTML 4.
steviesama
Aby przypisać dwie linie kodu React do zmiennej, użyj nawiasów wokół obu linii. ()
Vael Victus
1
Naprawiłem to za pomocą pre-wrap. Oto moja odpowiedź na podobne pytanie: stackoverflow.com/a/55466235/5346095
JS dev

Odpowiedzi:

73

Możesz spróbować umieścić elementy div dla każdej linii

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

Lub

render() {
    var text = "One\nTwo\nThree";
    return (
    <div>
        {text.split("\n").map((i,key) => {
            return <div key={key}>{i}</div>;
        })}
    </div>);
}
Sergio Flores
źródło
5
Lubię to. Myślę, że mógłbym też zrobić z tego <MultilineText>komponent!
Aaron Beall
13
Dlaczego miałbyś <div>formatować linie tekstu? <p>wydaje się bardziej poprawna semantycznie.
kost
1
Czy to na poważnie, jak należy to zrobić? Rozumiem, że to działa, ale powoduje to bałagan w znacznikach. A jeśli użytkownik chce skopiować ten tekst? Szczerze mówiąc, wina leży w obsłudze, a nie w rozwiązaniu. To może być najlepsza opcja, ale wow.
kevincoleman
1
Nawet nie myśl o reakcji, pomyśl, jak sobie z tym poradzić używając HTML. Zdecydowanie najlepszym rozwiązaniem jest tworzenie elementów div, umieszczanie tagów BR lub bloków. Moim zdaniem to ten sam scenariusz dla HTML / reaguj.
Sergio Flores
244

Utwórz nową klasę CSS

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

Wyświetl swój tekst z tą klasą CSS

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

Renderuje ze znakami końca linii (sekwencje białych znaków zostaną zwinięte w jedną białą spację. W razie potrzeby tekst będzie zawijany). Lubię to:

One
Two
Three

Możesz również rozważyć wstępne zawijanie. Więcej informacji tutaj ( właściwość odstępu CSS ).

andersvold
źródło
2
To świetna alternatywa dla odpowiedzi, którą przyjąłem i zasługuje na upvotes, ale czuję, że powinienem wspomnieć, że spróbowałem i miałem problemy z układem / przepełnieniem / renderowaniem; żadna z opcji białych znaków nie wydawała się działać poprawnie we wszystkich przypadkach, w których potrzebowałem wówczas poprawki, podczas gdy zaakceptowana odpowiedź działała.
Aaron Beall
1
Na pewno najlepsza odpowiedź. Po prostu dodaj CSS i nie musisz używać mapy ani niczego innego. Dzięki.
Frederiko Cesar
26

Możesz użyć właściwości CSS „white-space: pre”. Myślę, że to najłatwiejszy sposób radzenia sobie z tym.

Brick Yang
źródło
Najlepsza odpowiedź, imo: to jest problem z wyświetlaniem, więc najlepiej rozwiązać go w css (nie zmieniając html)
Bogdan D
12
white-space:premiał taki sam efekt jak white-space:nowrapu mnie, tzn. tekst przepełnił swoje opakowanie. Użycie white-space:pre-wrapzamiast tego rozwiązało ten problem.
rorymorris89
Tylko użycie "pre" spowoduje, że tekst przekroczy / nie zawinie kontenera. Użyj white-space: pre-line;zamiast tego.
Frederiko Cesar
6

Tutaj najczystsze rozwiązanie (afaik):

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

Zamiast you możesz również użyć <div style={{whiteSpace:"pre"}}>lub dowolnego innego elementu bloku html (takiego jak spanlub pz tym atrybutem stylu)

Philipp Munin
źródło
Dziękuję po wypróbowaniu różnych sposobów, to jedyne rozwiązanie, które u mnie zadziałało.
Saurabh Rana
2

Spróbuj tego,

render() {
    var text = "One\nTwo\nThree";
    return <div style={{whiteSpace: 'pre-line'}}>{text}</div>;
}
Codemaker
źródło
0

Renderuj rozdzielony tekst „Moja linia pierwsza \ nMoja druga linia \ nWhatvs ...” w normalnym obszarze tekstowym HTML. Wiem, że to działa, ponieważ właśnie go dzisiaj użyłem! Spraw, aby obszar tekstu był czytany tylko wtedy, gdy musisz, i stosownie do niego styl.

joedotnot
źródło
0

Możesz użyć -webkit-user-modify: read-write-plaintext-only;w swoim div. Na przykład sformatuje i zrozumie takie rzeczy, jak \ n i \ p.

Frederiko Cesar
źródło
0

Możesz skorzystać z tagu textarea w html, później możesz dodać styl do tagu textarea. Prawie rozwiązuje wszystkie problemy, w tym podziały wierszy i spacje tabulatorów. Cheerzz ...

np .: Twój render będzie wyglądał jak poniżej

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

Wynik:

One
Two
Three
Darshuu
źródło
0

Możesz bezpiecznie uruchomić String.rawzamiast tego dla tego typu wartości.

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

Możesz także po prostu użyć <pre>tagu, który skutecznie robi to samo, ale jest mniej semantycznie jasny, jeśli używasz go już do innych celów w swojej aplikacji.

trevoro
źródło
0
<div style={{ whiteSpace: "break-spaces" }}> {JSON.stringify(state, null, " ")} </div>
Adam Rybiński
źródło