Reputation: 55
I am using react and pulling from an api where comments are held. There are multiple comments with br
tags because the api come from a php user. I am trying to replace the br
tags in each string with an actual line break. I am also using react, so jQuery is a no-go.
This is what I have:
this.state.notes.forEach((note) => {
const fixed = note.body.replace(/<br>/g, "\r\n");
rows.push(<ListGroupItem hover href="#" className="whiter" key=
{note.id}>
<div className="d-flex justify-content-between">
<h5 className="mb-1">{ note.name }</h5>
<small>{ commentDate }</small>
</div>
<p className="mb-1">{ fixed }</p>
</ListGroupItem>)
}
I have replaced it with spaces and it worked, but it hasn't worked with the line break. Where am I going wrong?
Edit 1: @T.J. Crowder I added how it's displayed on the page. rows
is an empty array and the ListGroupItem
's come from MDBootstrap.
Upvotes: 4
Views: 5087
Reputation: 1074495
The way you're replacing <br>
is fine, other than you might want to allow for spaces before the closing >
, and an optional /
just before the >
as well:
const fixed = note.body.replace(/<br\s*\\?>/g, "\r\n");
But that doesn't solve the problem that what you're getting is HTML, not plain text. You're best off getting the other end to send you the text rather than HTML. By sending you HTML, they're giving you a significant amount of work to do. You don't want to just replace <br>
with line breaks, because HTML can have all sorts of other things in it, such as named character entities (<
, &
, etc.), numeric character entities (such as c;
), script
tags (opening the possibility of XSS attacks), etc. React is smart when you output text and escapes <
and &
and such to that they're output as those characters, not HTML, so if the HTML you receive has, say, <
in it, you'll actually see &
, l
, t
, and ;
in the display, which isn't idea. If your starting point is HTML, interpreting it correctly without allowing scripts and such is difficult. (React does have an option for injecting raw HTML, but it's got an absurdly-awkward name for a reason. :-) )
Once you have the text, with standard line breaks (\r
, \n
, or \r\n
), you can render each line in its own div
to get line breaks in the output, since normally in HTML a line break (or any run of whitespace) is just a single space:
<p className="mb-1">{
fixed.split(/[\r\n]+/).map(line => <div>{line}</div>)
}</p>
Example:
const Example = ({fixed}) => {
return <p className="mb-1">{
fixed.split(/[\r\n]+/).map(line => <div>{line}</div>)
}</p>;
};
const str =
"This is a string with line breaks.\r\n" +
"Line 2\r\n" +
"Line 3";
ReactDOM.render(
<Example fixed={str} />,
document.getElementById("root")
);
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.4.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.4.2/umd/react-dom.production.min.js"></script>
Upvotes: 3