I have html saved from wysiwyg editor and fetched from database, I need to display the content which I usually do with
<div dangerouslySetInnerHTML={{__html: content}} />
but now I need to use the formatted content inside another component,
so I am hoping if there is a function to return the markup like this
var formattedContent = getMarkup(content)//expecting this to do what dangerouslySetInnerHTML does
<Highlight search="Condominium" >
{formattedContent}
</Highlight>
because this isn't working
<Highlight search="Condominium" >
<div dangerouslySetInnerHTML={{__html: content}} />
</Highlight>
Any help is appreciated as I am nearly struggling for with this more than a day.
What I am trying above is
npmjs.com/package/react-highlighter -- it highlight matched words, but I need to highlight not just plain text but html
The dangerouslySetInnerHTML value is an object with __html as key and your HTML content as value.
<Highlight search="Condominium" >
<div dangerouslySetInnerHTML={{__html: content}} />
</Highlight>
Update:
The Highlight component has already an Attribute innerHTML. You don't need to use dangerouslySetInnerHTML in your case.
From official Documentation:
<Highlight innerHTML={true}>{content}</Highlight>
Related
I am fetching HTML from my backend (generated by CKEditor) I am then using DangerouslySetInnerHTML to render said HTML like this :
const parsed = DOMPurify.sanitize(album.description)
<div dangerouslySetInnerHTML ={{ __html: parsed }} className={styles.albumDescription} </div>
It works fine and I'm able to render my HTML. However I'm having troubles with embed medias. CK editor returns the media link in a <oembed /> tag.
What I would like to do is that each time there is a <oembed />, insert them into <ReactPLayer /> component.
I understand I could probably use vanilla js DOM manipulation and use something like getElementsByTagName but I assume that's not great practice to do that in react.
Using the DOM manipulation the challenge would be to verbatim replace all the attributes that <oembed .... /> would have, not impossible though.
If the incoming html string is not HUGE (running in several MBs), a simple string regex manipulation should do the trick:
Option 1: If you are sure that it'll always be <oembed ... />, then the following works.
const desc = album.description;
oembed_2_player = desc.replaceAll(/\<oembed ([^\/]*)\/\>/gi,"<ReactPLayer $1 />");
const parsed = DOMPurify.sanitize(oembed_2_player)
<div dangerouslySetInnerHTML ={{ __html: parsed }} className={styles.albumDescription} </div>
Option 2: If you expect <oembed ....> ... & you want to translate it into <ReactPlayer ..same-as-in-oembed..> ..dito... then
const desc = album.description;
oembed_2_player = desc.replaceAll(/\<(oembed) ([^\>]*)\>([^\<]*)<\/\1\>/gi,"<ReactPLayer $2>$3</ReactPLayer>");
const parsed = DOMPurify.sanitize(oembed_2_player)
<div dangerouslySetInnerHTML ={{ __html: parsed }} className={styles.albumDescription} </div>
Hope this helps 👍
I have a div that use dangerouslySetInnerHTML to set some text that come from the server. Something like this:
<Wrapper>
<div
ref={previewRef}
dangerouslySetInnerHTML={{ __html: preview }}
/>
</Wrapper>
The preview content it's something like <p> Some context </p>. I need to access offsetHeight and scrollHeight of that rendered p tag instead of the div.
According to #evolutionxbox answer. The solution is:
previewRef.current.querySelector('p')
Important to validate that previewRef.current is not undefined.
So I given this code:
render() {
console.log(this.props, 'ey');
const var1 = "<div className={{blahblah}} style={{width: '10px'}}>{textvar}</div>"
return (
<div dangerouslySetInnerHTML={{ __html: `${var1}` }}>
</div>
);
}
Of course that's just an example, but the var1 should be a big chunk of html file in jsx format, however doing that one renders them as they are and doesn't convert them to regular html.
I also tried setting innerHTML via refs on componentDidMount but same problem happens.
this is what it should look like when it renders:
<div class="blahblah style="width: 10px"}}>the variable text</div>
Any help would greatly appreciated. thanks!
You need to do this to use ES6 interpolated string literals (inaccurately called template literals by the spec):
<div dangerouslySetInnerHTML={{ __html: `${var1}` }}>
But this would be simpler:
<div dangerouslySetInnerHTML={{ __html: var1 }}>
However, in your string for the inner html, you may want to use an interpolated string literal if what you want is to use the values of the blahblah and textvar variables. Note you need to use class instead of className since React will just set the inner html rather than treat it as JSX and className is only for JSX.
const var1 = `<div class=${blahblah}>${textvar}</div>`;
If you are using a class, no need to also use the style keyword. Just set the width in your CSS.
You can see a working example of the above on CodePen.
There is a "portal" pattern which specifies that an element should be appended to the document.body. I want something similar to this, however, it must append to a specific component. My basic layout component would look as follows (Codepen Here):
<div className={styles.container}>
<div className={styles.header}>
<Navbar />
</div>
{/* Here be the problem */}
<PortalTarget />
<div className={styles.content}>
<div className={styles.leftSidebar}>
<SidebarNav />
</div>
<div className={styles.main}>
{children}
</div>
</div>
</div>
Instead of rendering to document.body, it should find the PortalTarget element (ideally only one would be rendered) and then append the <Portal> into that DOM Node.
I am specifically having trouble creating and storing a reference to the <PortalTarget>, I can't seem to find a good way to do it without redux.
Is there a way to do this in React?
If using an external library issue not a concern, just type "react portal" or "react gateway" on any search engine.
There a few battle-tested libraries out there.
I am trying to add br tag between the text in react.
can you guys tell me how to add it.
I tried adding br tag... but if I add I get tag in the browser.
providng my code below.
can you guys tell me how to fix it.
let sportsDescription = '';
if(sportsInfo !== '' && !isSportsSetupActive) {
sportsDescription = 'testing <br /> testing';
}else if(isSportsSetupActive) {
sportsDescription = 'testing <br /> testing';
}
return (
<div id="main" className="section flex-container flex-full">
<section className="page-content flex-item">
<section className="gray-box">
<h2>Welcome to your dashboard{formatName}.</h2>
<p className="ft-intro ft-day1 ft-day2">{sportsDescription}</p>
</section>
</section>
</div>
);
From the ReactJS Docs...
In general, setting HTML from code is risky because it's easy to inadvertently expose your users to a cross-site scripting (XSS) attack. So, you can set HTML directly from React, but you have to type out dangerouslySetInnerHTML and pass an object with a __html key, to remind yourself that it's dangerous.
In your example, {sportsDescription} is interpreted as a string. React won't see anything inside that variable as a DOM element. That's why your <br/> only renders as a string.
Alternatively, you could do this (but it's generally a bad idea)...
<p
className="ft-intro ft-day1 ft-day2"
dangerouslySetInnerHTML={{__html:sportsDescription}}
/>
This way, React correctly recognized your intent to include HTML inside the string sportsDescription and renders the desired <br/> element.
Here's a quote from an article that goes into greater detail about Getting Started with ReactJS:
The React module has a createClass method that takes an object as its only parameter. We define only one key to start with: render. The value of render is a function that returns a virtual DOM element. One of the keys to React’s performance is its virtual DOM abstraction. Essentially, it’s a difference engine that calculates the difference between the existing DOM and the DOM that is to be rendered and only modifies the necessary elements and attributes. Inside the render function, you may have noticed that I included HTML markup. That’s JSX. It won’t pass validation as legal Javascript. Instead, it requires the Babel transpiler.
JSX only looks like HTML. JSX is just a syntactic extension of Javascript, where every JSX "tag" is actually a call of React.createElement function. SO you can't treat JSX as HTML, and therefore you can't simply use strings with HTML inside and expect them to act like DOM. What you should do is return other valid JSX:
let sportsDescription = '';
if(sportsInfo !== '' && !isSportsSetupActive) {
sportsDescription = (
<span>testing<br />testing</span>
);
} else if(isSportsSetupActive) {
sportsDescription = (
<span>testing<br />testing</span>
);
}
return (
<div id="main" className="section flex-container flex-full">
<section className="page-content flex-item">
<section className="gray-box">
<h2>Welcome to your dashboard{formatName}.</h2>
<p className="ft-intro ft-day1 ft-day2">{sportsDescription}</p>
</section>
</section>
</div>
);
Here,
<span>testing<br />testing</span>
is actually four calls of React.createElement, the first one is for span element, and three other are for its children: text node, br, text node.
Please read the documentation carefully.