admin管理员组文章数量:1290776
I'm retrieving an HTML string from SharePoint and need to parse and modify the data and build a react element to be displayed in my react application.
Basically, I have code (as string) returning to me in a format similar to:
"
<div>
<div data-sp-canvasdataversion="1">This could be a header</div>
<div data-sp-canvasdataversion="1"><img src="titleimage.jpg"></div>
<div data-sp-canvasdataversion="1"><a href="pdfLink.pdf">This is a link to a PDF</a></div>
</div>
"
and from that I need to cycle through the children and build a new React element containing some parts of what was returned and some new parts such as
<div>
<div data-sp-canvasdataversion="1">This could be a header</div>
<div data-sp-canvasdataversion="1"><img src="titleimage.jpg"></div>
<PDFViewer file={""pdfLink.pdf""}></PDFViewer>
</div>
I was originally using dangerouslySetInnerHTML which worked to simply display the data, but now i need to remove a chunk of the html, create a react element based on the data and inject the new element back into the code. Since i'm trying to insert a ponent now, vanilla html won't work.
I'm able to cycle through the children by converting it to a dom node but I can't figure out how to use a dom node or element as a React Element Child.
I've tried:
let element = React.createElement('div', {}, HTMLString);
let node = document.createRange().createContextualFragment(HTMLString).firstChild;
let element = React.createElement('div', {}, node);
let node = document.createRange().createContextualFragment(HTMLString).firstChild;
let node2 = document.createElement("div");
node2.appendChild(node);
node2 = node2.firstElementChild as HTMLDivElement;
let element = React.createElement('div', {}, node2);
None work as needed and give me the error Objects are not valid as a React child (found: [object HTMLDivElement]).
or similar.
What i need is something like:
let element = React.createElement('div');
let node = document.createRange().createContextualFragment(HTMLString).firstChild;
node.childNodes.forEach(child => {
if(...//child IS NOT pdf)
element.appendChild(child)
else if(...//child IS pdf){
...
element.appendChild(<PDFViewer file="linktopdf.pdf">)
}
})
Then I would expect to be able to use that in render
render {
...
return(
<div className="container">
{element}
</div>
);
}
Please let me know if this is even possible and how. The only possible solution I could think of was maybe saving the child elements as strings and using dangerouslySetInnerHTML to generate all of them but I really want to get away from using dangerouslySetInnerHTML, especially like that.
I'm retrieving an HTML string from SharePoint and need to parse and modify the data and build a react element to be displayed in my react application.
Basically, I have code (as string) returning to me in a format similar to:
"
<div>
<div data-sp-canvasdataversion="1">This could be a header</div>
<div data-sp-canvasdataversion="1"><img src="titleimage.jpg"></div>
<div data-sp-canvasdataversion="1"><a href="pdfLink.pdf">This is a link to a PDF</a></div>
</div>
"
and from that I need to cycle through the children and build a new React element containing some parts of what was returned and some new parts such as
<div>
<div data-sp-canvasdataversion="1">This could be a header</div>
<div data-sp-canvasdataversion="1"><img src="titleimage.jpg"></div>
<PDFViewer file={""pdfLink.pdf""}></PDFViewer>
</div>
I was originally using dangerouslySetInnerHTML which worked to simply display the data, but now i need to remove a chunk of the html, create a react element based on the data and inject the new element back into the code. Since i'm trying to insert a ponent now, vanilla html won't work.
I'm able to cycle through the children by converting it to a dom node but I can't figure out how to use a dom node or element as a React Element Child.
I've tried:
let element = React.createElement('div', {}, HTMLString);
let node = document.createRange().createContextualFragment(HTMLString).firstChild;
let element = React.createElement('div', {}, node);
let node = document.createRange().createContextualFragment(HTMLString).firstChild;
let node2 = document.createElement("div");
node2.appendChild(node);
node2 = node2.firstElementChild as HTMLDivElement;
let element = React.createElement('div', {}, node2);
None work as needed and give me the error Objects are not valid as a React child (found: [object HTMLDivElement]).
or similar.
What i need is something like:
let element = React.createElement('div');
let node = document.createRange().createContextualFragment(HTMLString).firstChild;
node.childNodes.forEach(child => {
if(...//child IS NOT pdf)
element.appendChild(child)
else if(...//child IS pdf){
...
element.appendChild(<PDFViewer file="linktopdf.pdf">)
}
})
Then I would expect to be able to use that in render
render {
...
return(
<div className="container">
{element}
</div>
);
}
Please let me know if this is even possible and how. The only possible solution I could think of was maybe saving the child elements as strings and using dangerouslySetInnerHTML to generate all of them but I really want to get away from using dangerouslySetInnerHTML, especially like that.
Share Improve this question asked Jun 6, 2019 at 20:27 SethSeth 1,0721 gold badge10 silver badges18 bronze badges 3-
You may want to try to use
react-html-parser
npmjs./package/react-html-parser to convert HTML into React ponent and then use that for your purpose. – Rikin Commented Jun 6, 2019 at 20:43 -
1
Not sure about parsing, but when you want to render string as raw
HTML
in react, the only API available for that is dangerouslySetInnerHTML – Sagiv b.g Commented Jun 6, 2019 at 20:48 - Check out react-hyperscript example in docs. You can use the lib if you want, or just implement it from scratch using the same idea since you were able to get them into DOM nodes already. – marsheth Commented Jun 6, 2019 at 23:45
2 Answers
Reset to default 4For below React v17.0: try this react-html-parser
For React v17.0 and above: try this fork (thanks to @thesdev pointing that out)
I ended up doing what I didn't want to which is using dangerouslySetInnerHTML. If anyone es up with a better solution, please feel free to share.
async getArticleComponents(data: any) {
if (!data)
return null;
let slides = []
let node = document.createRange().createContextualFragment(data).firstChild;
let children = node.childNodes;
for (let i = 0; i < children.length; i++) {
var element = (children[i] as HTMLDivElement);
var controlElement = element.attributes.getNamedItem("data-sp-controldata");
var jObj = controlElement ? JSON.parse(controlElement.value) : null;
if (jObj.controlType === 3) {
var childEle = element.firstElementChild;
var webPartData = childEle.attributes.getNamedItem("data-sp-webpartdata");
var wpJObj = webPartData ? JSON.parse(webPartData.value) : null;
if (wpJObj.title == "File viewer") {
let ext = (/.*\.(.*)/i).exec(wpJObj.properties.file)[1].toLowerCase();
if (ext === "pdf") {
var pdf = await fetch(`/api/SharePoint/GetFile?url=${encodeURIComponent(`${wpJObj.serverProcessedContent.links.serverRelativeUrl}`)}`)
.then(res => res.text())
.then(pdf => pdf ? `data:application/pdf;base64,${pdf}` : null);
slides.push(<PDFViewer key={jObj.id} file={{ pdf, fileName: "test" } as IPdfMeta} />);
}
} else
slides.push(<div key={jObj.id} dangerouslySetInnerHTML={{ __html: element.outerHTML }}></div>);
}
else if (jObj.controlType !== 0) {
slides.push(<div key={jObj.id} dangerouslySetInnerHTML={{ __html: element.outerHTML }}></div>);
}
}
return slides;
}
本文标签: javascriptCan I create a React Element from an HTML string or dom nodeelementStack Overflow
版权声明:本文标题:javascript - Can I create a React Element from an HTML string or dom nodeelement - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741510907a2382600.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论