I'm using a third party library in React and would like to wrap my shared component around a div created by this library.
My code:
<div>
<SharedComponent/>
<ThirdPartyComponent/>
</div>
Desired output:
<div>
<ThirdPartyComponent>
<SharedComponent>
<ThirdPartyComponentDiv/>
</SharedComponent>
</ThirdPartyComponent>
</div>
I've looked into append, but have only seen examples of creating a document element (document.createElement), but I need to use a shared component already built.
Looking for some direction and where I can go from here. Thank you in advance!
Related
I have a React component
<Text>
<div dangerouslySetInnerHTML={{ __html: apiContent}} />
</Text>
that displays HTML coming from an API that may look like the following:
<div>
<p>text</p>
<p>more text</p>
<p>more text</p>
<p>more text</p>
<p>still more text</p>
</div>
How do I insert an image, which is another React component, between the 2nd and 3rd p tag?
I know how to do it in vanilla JS, but have trouble doing it the React way.
I'd be curious to see the other answers, but I feel like inserting a React component inside some raw HTML is pretty much impossible. The options I can think of are:
use some library to turn the raw HTML into a tree of React components, and hopefully this library will also include a way to inject custom components in specific places (I don't know any such library, but there probably is one)
edit the raw HTML to insert an empty container with a unique id at the place you need it (for instance by parsing the HTML into a DocumentFragment, using vanilla JS to insert a div, turning it back into a string, and setting it as innerHTML as you already do), and then use a React portal to inject a React component into that container. Pretty messy...
If it is a react component then it is not html so not logical to put it inside dangerouslySetInnerHTML tag.
you need to rewrite this react component to an HTML string and work with the html that is coming from API as a string.
that means you can split the incoming string of html on the second closing p tag
and add the new html string in the middle.
Could you tell me the way to do something like this in tailwindcss:
first[&>.a-child-class]:text-5xl
I'm trying to style the first element by the way passing classes when it's rendering,I want to change its child's style, but the code above did not work.
I tried to put that classes inside component by default, but I realized, the component need to reusable, so that it is not reasonable.
please help meeeee.
thank you so much, have nice day.
In tailwind 3.1, arbitrary variants can be stacked with built-in modifiers or with each other, just like the rest of the modifiers in Tailwind. You can see the document here. You are missing : after first.
Example:
<div className="first:[&>.a-child-class]:text-5xl">
<p className="a-child-class">first</p>
<p className="a-child-class">second</p>
<p className="a-child-class">third</p>
<p className="a-child-class">forth</p>
</div>
Tailwind Play demo
I am currently using Next.JS to create a static website with the main objective to have a very good SEO-optimized website.
Everything works fine and the website is correctly deployed with Vercel, but I have noticed that part of the content is not present directly in the HTML files.
For instance, I have a component that loops over an array of data, using the array map method, like this:
{imageTexts.map((image) => (
<ImageText
key={image.title + 'TitleImage'}
title={image.title}
description={image.description}
size={imagesSize}
image={image.image}
/>
))}
Once the website is deployed to Vercel, I search inside the HTML file for the information/strings contained in the array of data (imageTexts), but I can't find them. I guess Next.JS uses javascript to target some sort of div and then loops over its own JSON file to dynamically display content.
For me, this seems to kill a lot of the SEO advantage that static websites have over SPA. Is there any way I can have those strings directly inside my HTML files?
I am still not 100% sure this is caused by the map method, but I don't find any other explanations. Especially because other dynamically loaded components don't have the same problem. For example, this component string can be found on the HTML file, without a problem:
{title ? (
<Text
type="h2"
textAlign="center"
>
{title}
</Text>
) : null}
If you are mapping over ImageTexts on the server and that component renders HTML tags, then that HTML should be sent on the first-page load, and you could see it if you do CTRL+U or disable javascript.
Ok, I have just found that the reason. It has nothing to do with the map method. I was actually using the <Remark> component from library called react-remark. It seems it does not play well with Next.JS
I'm very new to typescript.
I've got a wrapper component, and a bunch of child components that I want to display.
So, something like this is in my parent component html: <component-card [someData]=someData></component-card> works just fine and displays my component. But how do I display a list of them?
Simply doing <li *ngFor="let card of componentCardArray"></li> doesn't work. I tried different ways
Most tutorials just cover simple types, I searched for hours and can't find a way to do it.
Okay, I figured it out! I was forgetting to put the selector after the whole *ngFor directive thing. So, here is how my components are displayed now in my wrapper.html:
<div *ngFor="let card of cardArray">
<component-card [myData]=myData></component-card>
</div>
I'm new on React (I more at ease w/ jQuery or AngularJS). I have a special case and I don't find a good way to resolve it...
My app contains an area which is like a "document viewer". It loads an HTML content from the backend (via API, using Fetch) and inject it in the "viewer" component. The HTML content loaded looks like an "university report" (it's just a formatted text, only <span> and <p> with class="..." attributes, nothing more).
Ex : <p>Lorem ispum <span>some text</span> loreb bis <span>ipsum</span></p> ...
I load the content, and inject it this way in the render() of my component <Viewer> :
<div dangerouslySetInnerHTML={ getFreshlyLoadedHTML() } />
Easy, it works just fine !
But... Now, I want to inject some "interactive" components in the loaded HTML. For example, some button to give a feedback etc. The API must decide where to place the component between the words/nodes of the formatted text (HTML).
Ex :
<p> Lorem ispum <span>some text</span>
loreb bis <span>ipsum</span>
<MyFeedbackButton paragraph="1.3"/>
</p><p>Other Lorem Ipsum<p><span>...</span>
There, I'm stucked because I cannot use dangerouslySetInnerHTML if there are components inside the loaded HTML...
First attempt : I've tried modifying the API, and instead of sending the HTML in a string to the app, I send a custom JSON structure that represents almost the final JSX structure that I want. Then, in my react page, the render function only have to parse the JSON and build the JSX (here, a JsFiddle example if it's not clear : https://jsfiddle.net/damienfa/69z2wepo/34536/ )
It works, but I can't believe it's the good way...
I see a major problem : all the HTML node (span, p...) that I build from the render function are referenced by reactJs, is it really necessary ? Mostly, there are "dead" nodes (I mean, dom node that won't never changed, this is static formatted text).
Just take a look a all those "data-reactid" on nodes that never will be interactive...
What would be your advice on that case ?
What about my attempt with a JSON-structure sent by the API ?
Is there a way to say to react "do not reference that element" ?
Do you clearly see a better solution to my problem ?
Your current workflow is not very secure and subject to many potential errors and open doors, especially concerning code injection ...
The overload due to react tracking the nodes is not an issue, React could track 10 000 nodes and not have a problem (well actually on many of my apps React has more than 100 000 nodes to care about and it still rurns perfectly).
I see different solutions here:
If there are only 3 or 4 possibilities of dynamic components and order, you might have components like "templates" to which you would simple send text arguments. This is the safest and easiest option.
If it doesn't suit your use-case but the JSON file can contain only a limited set of components, the components should be located in your main app, and then rendered with custom props from the JSON. Actually given the structure of data you could consider using xml instead of json and build a xml tree that you would parse and render. Only components from your white list would be rendered and it would limit drastically the potentials security issues. If needs quite some work on the XML parser though.
If the JSON file can contain many many different and unpredictable components or if the behaviour of those components is largely dynamic and independant of your app, you might as well consider using an iframe, with its own JS and HTML, so that this part of the code is isolated from the rest.
Try using an inline anonymous function within the inner content from within React using JSX. It works! Just be careful about how you wire up the data so there isn't a route where a user can inject HTML from an input or text field.
<div className="html-navigation-button">{(() =>
{
const CreateMarkup = ( sNavItemName :string ) => {
return {__html: sNavItemName };
}
var sTextToAddHtmlTo = props.nextNavItem.name.toString();
sTextToAddHtmlTo = sTextToAddHtmlTo.replace( "/", "/<wbr>" );
return (
<div dangerouslySetInnerHTML={CreateMarkup( sTextToAddHtmlTo )} >
</div>
);
})()}
</div>
I didn't override the React internals of 'render()', but only used a React Component with props wiring to pass down data to it for rendering.
I added the hook for 'dangerouslySetInnerHTML' deep within the return content of the React Component so there would be no easy way to intercept and manipulate it.
As such, there is no 100% guarantee on safety, but that's where adding good security to web services, databases, and use of CORS and CORB would be helpful to lock down security risks.