Inject component into specific div without Redux - javascript

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.

Related

react.js image onClick not working for some reason, while same function works for another div

i am making Faq questions in react and my question div displays text when clicked on whole body as shown below:
Here is my react code. div with class "question-body" works with onclick but when I click the Plus img it has no action,any mistakes?
export default function Question({data}){
let imagid = 'img'+data.id;
function toggle(){
document.getElementById(data.id).classList.toggle('question-p') ;
document.getElementById(imagid).classList.toggle('rotateimg');
}
return(
<div className="column width100 question">
<div onClick={() => toggle()} className="question-body">
<div className="flex-between">
<label className="faq-question">{data.question}</label>
<img onClick={() => toggle()} id={imagid} className='togglequestion' src={togglequestion}></img>
</div>
<p id={data.id} className='none' dangerouslySetInnerHTML={{ __html: data.answer }}></p>
</div>
</div>
)
}
even though the answer is pretty simple here, it would require you to redo most of your code.
In order to be working with React.js effectively, you need to learn the basics (component state management,... ) - https://reactjs.org/docs/getting-started.html
I highly encourage you not to use dangerouslySetInnerHTML as it can expose your code to easy exploits.
With React.js, you don’t really want to use Document Object Model APIs (via toggle function)

Vue only renders first custom component issue

I have a simple Vue app where I'm trying to render multiple custom components, here's what I'm trying:
JS
Vue.component('refinement-list', {
props: ['attribute', 'title'],
template: '<div>{{attribute}} - {{title}}</div>'
});
new Vue({
el: '#app'
});
HTML
<div id="app">
<refinement-list attribute="test" title="Test" />
<refinement-list attribute="sample" title="Sample" />
</div>
However the problem is that only the first component is rendered, see working example:
https://codepen.io/javiervd/pen/vYBpQMm
I tried registering the component locally instead but no luck. I'm also using Vue with a script tag in my app because I can't use a build system for this particular project, not sure if that matters.
Can anyone point me in the right direction? Thanks.
Since you are defining the template in the DOM, you can't use self-closing tags for the custom components.
This should work:
<div id="app">
<refinement-list attribute="test" title="Test"></refinement-list>
<refinement-list attribute="sample" title="Sample"></refinement-list>
</div>
This limitation doesn't exist in template strings or Single File Components.
You can read more about this here: https://v2.vuejs.org/v2/style-guide/#Self-closing-components-strongly-recommended
You should give like this in the HTML section if you want to use the self-closing tags. But it's not recommended for DOM Templates
<div id="app">
<div>
<refinement-list attribute="test" title="Test1" />
</div>
<div>
<refinement-list attribute="test" title="Test2" />
</div>
</div>
I forked your codepen and can confirm this is working with the separate closing tag style, in place of using self-closing tags for the components.
<div id="app">
<refinement-list attribute="test" title="Test"></refinement-list>
<refinement-list attribute="sample" title="Sample"></refinement-list>
</div>
ref: https://codepen.io/edm00se/pen/pozpqym?editors=1010
The self-closing tag versus (full?) closing tag is discussed in the vue style guide page (v2) and it is expressed that for string templates (as I suspect codepen is doing when loading your HTML content), to use the closing tag, while self-closing are fine in single-file components, JSX, and string templates (things which are processed during build and component names are better known).

How to Modify Props of Non-immediate Children

I am transferring my site from a LAMP stack to a MERN stack. On the old site, I had a dropdown where a button would toggle the display of a div of one of its parents siblings. The structure looked like this:
<div class="header">
<div class="header-option">Option 1</div>
<div class="header-option" id="toggle-dropdown">Option 2</div>
<div class="header-option">Option 3</div>
</div>
<div id="dropdown-content">
Lorem ipsum
</div>
I would use JQuery to detect a click on #toggle-dropdown and then toggle the display of #dropdown-content. I turned this into a reusable plugin which could be used throughout the site. I would now like to do something like this in React with a reusable component. But I cannot seem to find the best practice for accessing and modifying the props of non-immediate children. I would of course wrap all of this in a <Dropdown> component to handle the state and to be able to abstract the process.
What I have thought of and found so far:
Recursing through the children, and their children, and so on, looking for a displayName and then cloning the child; but I don't believe this works in production.
Taking JSX as a Header and Footer prop to Dropdown, and then attempting to generate the DropdownButton and DropdownContent within components with the appropriate props; I feel like this would be a very inefficient, undesirable solution to something that I feel should be relatively easy.
ok, so you have:
<Header>
<Option />
<Option onClick={this.handleDropdownclick} props={props}>
<Dropdown>
</Option>
<Option />
</Header>
right?
just pass the onClick handler to option you want, no?
Or didn't I understand what are you asking?
If your tree is very deep and you don't want to pass manually each prop, may be use Context? https://reactjs.org/docs/context.html#contextconsumer

How do I use a custom DOM node to render to from within a react component

I have the following problem:
I want to write jsx code like
<div className="my-section">
<Window>
<div>Window content</div>
</Window>
</div>
<div className="window-container">
</div>
somewhere in my react content, but I want the window to render in a special DOM element with other windows, something like
<div class="my-section"></div>
<div class="window-container">
<div class="window">
<div>Window Content</div>
</div>
</div>
And to do this transparently I need to tell the component to render to a special DOM node from within the component. Is there a way to do this? If not, how should I accomplish the functionality I am looking for from within React?
You're looking for the special this.props.children list.
When you create a React component instance, you can include additional React components or JavaScript expressions between the opening and closing tags like this:
<Parent><Child /></Parent>
Parent can read its children by accessing the special this.props.children prop.
This will allow you to get the children defined inside your element, then insert them at an arbitrary point for render.
render() {
return (
<div className="window container">
<div className="window">{this.props.children}</div>
<div className="window"></div>
...
</div>
);
}

Proper way for seamless animations in ReactJS

I want to achieve the following DOM mutation using ReactJS, and animate it so that it cannot be noticeable by the end user.
<RootComponent>
<MyComponent id="a"/>
<div>
<MyComponent id="b"/>
</div>
<MyComponent id="c"/>
</RootComponent>
to
<RootComponent>
<MyComponent id="a2"/>
<div>
<MyComponent id="a"/>
</div>
<MyComponent id="c"/>
</RootComponent>
I successfully handle the animation (by moving the DOM Node around through the parent) and replace b with a, along with creating a new a2component.
The problem is, as soon as I ask React to rerender the root component (by placing a2), I run into an invariant violation. Indeed, I mutated the DOM manually, and data-reactids might be shuffled.
How could I complete such a workflow following React's best practices ?

Categories

Resources