I have a text file that I'm reading as a string, and then inserting into the DOM like so:
//the state gets set with the contents of a text file that has proper indentation
state = {
parsedText: null
}
//in the render function, this is how the text comes in
<p>{this.state.parsedText}</p>
When I iterate through the character codes, I can see that the 'enter' codes (i.e., 13) seem to work when I console.log the file (the indentation looks correct). Unfortunately, those character codes don't translate to HTML - the entire string just comes out as one solid chunk of text. So, what I'm trying to do is insert either <br> tags or \n characters or in order to make the breaks work in the HTML.
Here's what that looks like:
rawFile.onreadystatechange = () => {
if (rawFile.readyState === 4) {
if (rawFile.status === 200 || rawFile.status == 0) {
let allText = rawFile.responseText;
for (let i = 0; i < allText.length; i++) {
let uni = allText.charCodeAt(i)
if (uni === 13) {
console.log('enter!!')
allText = allText.substring(0, i) + "\n" + allText.substring(i + 1, allText.length - 1)
}
}
console.log("allText: ", allText);
console.log(typeof allText)
this.setState({
parsedText: allText
});
}
}
};
rawFile.send(null);
}
The \n insertions show up in the text string but are seemingly just ignored in the DOM. Is there a way to make this work? I've tried dangerouslySetInnerHTML and that does nothing.
Any ideas on how to make this work?
Had the same issue. just solved it.
All you need to do is to save the string as array. like so:
let text = "this is text without break down \n this won't work but will be one line"
let text = ["this is text with breakdown",
<br/>,
"this is the second line"];
You can also write utility function to do that for you:
const addLineBreak = (str: string) =>
str.split('\n').map((subStr) => {
return (
<>
{subStr}
<br />
</>
);
});
And use it:
<p>{addLineBreak("Hello \n World"}</p>
Here's an example on StackBlitz for your reference.
Hope that helps
If possible, avoid using dangerouslySetInnerHTML.
An alternate solution could be splitting your text into an array then rendering a new div for each "newline".
Of course, you would need to come up with a better key for the text, as there could be duplicate text - though that is a separate question in and of itself.
class Hello extends React.Component {
constructor(props) {
super(props)
this.state = {
parsedText: [
"Some text",
"More text",
"Keep on texting"
]
}
}
render() {
return <div>{this.state.parsedText.map(text => <div key={text}>{text}</div>)}</div>;
}
}
ReactDOM.render(
<Hello/>,
document.getElementById('container')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="container">
<!-- This element's contents will be replaced with your component. -->
</div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With