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 ?
Related
guys! I'm building React Native component that contains a UI pattern. This UI pattern will contain several smaller reusable patterns. This way:
<ListItem onPress={}>
<IconContainer>
<Icon />
</IconContainer>
<Body>
<Text>Content</Text>
</Body>
<Right>
<Action onPress={} />
</Right>
<ListItem>
Now I'm also building embedding size variants (small, medium/default and large) for some of these children, like this for example:
<IconContainer large={boolean} small={boolean}>
<Icon />
</IconContainer>
And since the are several children, I don't want to have the person using the component to have to specify the size variant for each one of the children. That'll also require them to know which one of the children have size variants and which one doesn't.
So, what I'm trying to do is to embed a props.large and a props.small into the parent and use that to change de value of the same prop if available in the children.
Any ideas of how to do that in a simple way?
(I suspect this is easy but I've been struggling with this for a while so I thought I'd ask for some help.)
Thanks in advance!
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
In my React component called Grid.js I am using a childcomponent called Pagination. It looks like this:
<StyledBox wrap py={12} px={18}>
<Header />
{state.data}
<Wrapper column justify="center" align="center" p={12}>
<Pagination onChange={this.handleChange} totalPages={10} />
</Wrapper>
</StyledBox>
It is a grid with some pagination functionality. When the user selects a page on the Pagination a changeevent will fire and a stateprop of the Grid will be set called state.data. The issue is that the pagination starts jumping around randomly: looks like the state has changed on the component.
Do I have to move the Pagination out of the Grid component and make it not a childcomponent?
Is the Pagination Component jumping around randomly because previously there was a specific length of data. Then when the this.state.data changes, the length of data is different? So then, the Pagination had to adjust it's positioning. Without more information, it seems like a HTML and CSS issue.
Try to set position: fixed; bottom: 1rem on the Pagination component css and see if it still jumps.
Also, regarding React Components, <Content /> and <Pagination /> components seem to be conceptually sibling and not parent-child related. So I would structure the app something like this:
<ParentContainer>
<Header />
<Content data={this.state.data} />
<Pagination onChange={this.handleChange} totalPages={10} />
</ParentContainer>
I've built in the past a "single page application" using nothing besides regular DOM manipulations with JQuery.
Nowadays, I'm rewriting the same app with React-Redux. After re-creating a certain page from my old JQuery app, I've noticed something disturbing: React does the same thing, MUCH MUCH slower. In fact, I'd say it's about twice as slow.
I started optimizing my component, and made sure it renders only when necessary. Yet, the entire process of re-rendering the HTML is slower.
What the component does: i fetch an array of 150 items from the server. Each item might have few items in it. So, my JSX has two nested map() functions:
{this.props.duplicates.length>0 &&(
this.props.duplicates.map((duplicate_group,index)=>{
return(
<form key={index}>
{
duplicate_group.map((book)=>{
return(
<div key={book.id}>
<label className="specific_product_for_merging" htmlFor={book.id} id={book.id}>
<input type="radio" defaultValue={book.id} id={book.id} name="name" />
<span className="duplicates_span">Title:<Link to={`/products/${book.id}`}> {book.name}</Link> </span>
<span className="duplicates_span">ID: {book.id}</span>
<span className=" duplicates_span">Author:<Link to={`/advancedsearch?advancedSearch=byTitle&author=${book.author}`}> {book.author} </Link></span>
<span className=" duplicates_span">Publisher:<Link to={`/advancedsearch?advancedSearch=byTitle&publisher=${book.publisher}`}> {book.publisher}</Link></span>
<span className="duplicates_span">Available Copies: 0</span>
</label>
<br />
</div>
)
})
}
<input type="submit" className="submit_merged_titles btn btn-primary btn-sm" defaultValue="Merge" />
</form>
)
})
)
}
I was doing the same exact thing with Jquery. For some reason, the direct DOM manipulation seems to work much faster, in this case at least.
Note that each time i fetch new data(i'm using pagination), all of the data is different, so React has to re-render all DOM elements. But how come the entire process, of re-rendering the virtual DOM, and then rendering the DOM itself, is practically twice as slow?
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.