Reputation: 267
I'm writing a React-based application where one of the components receives its HTML content as a string field in props. This content is returned by an API call.
I need to:
For example, if I receive the HTML below, I should show the "Comment" button beside section with id "s101".
<html>
<head/>
<body>
<div id="content">
<section id="s101" accept-comments="true">Some text that needs comments</section>
<section id="s102">Some text that doesn't need comments</section>
</div>
</body>
</html>
Questions:
Things I've tried:
Upvotes: 8
Views: 14815
Reputation: 267
This answer comes from Chris G's code in the comments. I used the code with different sizes of documents and it works well. Thanks Chris G!
Posting the code here in case the link link in the comments breaks.
The solution uses DOMParser to parse the HTML content provided by the API call and scans it to find the content that should include the "Comment" button. Here are the relevant parts.
import React from "react";
import { render } from "react-dom";
const HTML =
"<div><section but='yes'>Section 1</section><section>Section 2</section></div>";
class DOMTest extends React.Component {
constructor(props) {
super(props);
const doc = new DOMParser().parseFromString(HTML, "application/xml");
const htmlSections = doc.childNodes[0].childNodes;
this.sections = Object.keys(htmlSections).map((key, i) => {
let el = htmlSections[key];
let contents = [<p>{el.innerHTML}</p>];
if (el.hasAttribute("but")) contents.push(<button>Comment</button>);
return <div key={i}>{contents}</div>;
});
}
render() {
return <div>{this.sections}</div>;
}
}
const App = () => (
<div>
<DOMTest />
</div>
);
render(<App />, document.getElementById("root"));
Upvotes: 11