I created a react app with many nested routes
.
One of my nested route is using a backend api that returns a complete HTML content
.
and I need to display that exact content with same HTML and styling in my UI.
I’m able to successfully achieve it by manipulating the DOM as per axios response inside useEffect
, using createElement
and appendChild
.
My Question is, Is there a cleaner way to use api returned HTML in a react App?
The whole philosophy behind using react is, to not modify the DOM and let react work on it when we update states or props.
Here is sample relevant code.
Item.js
...
...
useEffect( ()=>{
const fetchAndUpdateItemContent = async () => {
try {
const response = await axios.get(url);
var contentDiv = document.createElement("div");
contentDiv.innerHTML = response.data.markup;
document.getElementById(‘itemContent’)
.appendChild(contentDiv);
} catch (err) {
.....
console.error(err);
......
}
}
};
fetchAndUpdateItemContent();
},[itemId])
return (
<div id=‘itemContent'/>
);
}
What did NOT work
Ideally I should be able to have a state as itemContent
in Item.js
and be able to update it based upon server response like this. but when I do something like below, whole HTML merkup is displayed instead of just the displayble content.
const [itemContent, setItemContent] = useState(‘Loading ...');
...
useEffect( ()=>{
const fetchAndUpdateItemContent = async () => {
try {
const response = await axios.get(url);
setItemContent(response.data.markup)
} catch (err) {
.....
console.error(err);
......
}
}
};
fetchAndUpdateItemContent();
},[itemId])
return (
<div id=‘itemContent'>
{itemContent}
</div>
CodePudding user response:
You're actually trying to convert an HTML string to a JSX. You can assign it into react component props called dangerouslySetInnerHTML
Eg:
const Item = () => {
const yourHtmlStringResponse = '<h1>Heading 1</h1><h2>Heading 2</h2>'
return <div dangerouslySetInnerHTML={{__html: yourHtmlStringResponse}}></div>
}
You can try it here dangerouslySetInnerHTML-Codesandbox
CodePudding user response:
I believe you can use dangerouslySetInnerHTML