ReactDOM.hydrate replace container instead of inserting into - reactjs

First of all, there is a similar question to this one. I intentionally chose a similar title but this question is slightly different.
I have some server side rendered React code. It gives me HTML something like this:
<main>
<article>
<h2>Lorem ipsum</h2>
<p>dolor sit amet</p>
</article>
<article>
<h2>Lorem ipsum</h2>
<p>dolor sit amet</p>
</article>
<article>
<h2>Lorem ipsum</h2>
<p>dolor sit amet</p>
</article>
</main>
I am currently implementing partial hydration, ie. instead of having one big React app on my page that mounts at some root element, I am only hydrating parts of the page with their corresponding components.
That means I have an <Article> component like this
function Article() => (
<article>
<h2>Lorem ipsum</h2>
<p>dolor sit amet</p>
</article>
)
That I am mounting at the first article, ie.
const container = document.querySelector('main > article:first-child');
ReactDOM.hydrate(<Article />, container);
I was hoping that would hydrate the first <article> element and leave the rest alone, which works, except of using and hydrating the <article> element ReactDOM actually mounts inside the <Article /> inside the DOM element resulting in this HTML:
<main>
<article>
<article>
<h2>Lorem ipsum</h2>
<p>dolor sit amet</p>
</article>
</article>
^ -- <article> inside <article>, not cool
<article>
<h2>Lorem ipsum</h2>
<p>dolor sit amet</p>
</article>
<article>
<h2>Lorem ipsum</h2>
<p>dolor sit amet</p>
</article>
</main>
Now I am wondering if there is any way I can make ReactDOM use that container instead of inserting into it.

Related

NextJS 13 root.layout rendering NavBar at the bottom. Is there a way to consistently render NavBar at the top?

I'm experimenting building a Next13 app. The new layout is cool, but it is messing up the rendering. I don't entirely understand the ordering of rending objects within the layout:
Navbar.tsx
"use client";
import Link from "next/link";
export default () => {
return (
<span className="flex justify-between">
<h1 className="text-xl">Navigation Bar</h1>
<ul className="flex gap-4">
<li>
<Link href="/">Home</Link>
</li>
<li>
<Link href="/user/login">Login</Link>
</li>
<li>
<Link href="/user/signup">Sign Up</Link>
</li>
</ul>
</span>
);
};
layout.tsx
import "./globals.css";
import NavBar from "./NavBar";
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html className="bg-slate-500 font-robslab" lang="en">
<head>
<title>Stylitique</title>
<meta name="description" content="Generated by create next app" />
<link rel="icon" href="/favicon.ico" />
</head>
<header>
<NavBar />
</header>
<body>{children}</body>
</html>
);
}
page.tsx (HOME)
export default function Home() {
return (
<main>
<h1 className="text-green-500">HOME</h1>
<p>
{" "}
Lorem ipsum dolor sit amet consectetur adipisicing elit. Tempora
sapiente, expedita praesentium a eligendi dolorem maiores nihil
consectetur ipsum, repudiandae sed deserunt delectus, facere repellat
ipsam sit possimus voluptatibus error!
</p>
</main>
);
}
I tried:
putting the NavBar into a header outside the body.
putting it straight into the body.
with and without "use client".
added more data to "HOME" in order to render slower, I guess.
Anyone find a solution yet?
just put the component inside <body>
notice: no need of <header>
<head>
...
</head>
<body>
<NavBar />
{children}
</body>

ScrollWidth return ClientWidth instead the currect value

I'm building a slider with React and framer motion. My idea is to subtract scrollWidth with offsetWidth to get the remaining width of the element.
I always get the value of zero (somehow they are equal). I printed the object and I saw that scrollWidth value returns clientWidth instead.
In the object the value of scrollWidth is totaly different and I cant tell why.
I am Creating This Same Project Carousel Slider In Next.js
But I got scrollWidth is Undefined
I dont Know What Happend But..
I got scrollWidth is undefined
enter image description here
import React, { useEffect, useRef, useState } from 'react'
import { motion } from 'framer-motion';
import cardsUser from '../pages/CardsUsers'
const CardCaousel = () => {
const [width,setWidth] = useState(0)
const carousel = useRef()
useEffect(()=>{
setWidth(carousel.current.scrollWidth - carousel.current.offsetWidth)
},[])
return (
<div className="container max-w-full bg-gradient-to-r from-indigo-500 via-purple-500 to-pink-500 p-5 bggradient">
<div className="liveactionscontainer mt-20">
<h1 className='text-center text-white font-extralight text-6xl mt-2 mb-3'>Live Actions </h1>
<p className='font-extralight text-gray-500 text-center'>Lorem ipsum dolor sit amet consectetur, adipisicing elit. Perspiciatis, suscipit repellat
<br/>
inventore dolor quia quos molestias quae vitae? Eveniet nobis, laborum voluptas culpa libero similique.</p>
<div className="myflex flex justify-center" data-aos="fade-right">
<motion.div className="carousel">
<motion.div
drag="X"
dragConstraints={{right:0,left:-width}}
className="inner-carousel"
>
{cardsUser.map((e)=>{
return (
<motion.div className='item' key={e}>
<div className="mycolumn mb-10">
<div class="nft">
<div class='main'>
<img class='tokenImage' src={e.Imgsrc} alt="NFT" />
<h2>{e.name}</h2>
<p class='description'>Lorem, ipsum dolor sit amet consectetur adipisicing elit. </p>
<div class='tokenInfo'>
<div class="price">
<ins>◘</ins>
<p>0.031 ETH</p>
</div>
<div class="duration">
<button>Place bid</button>
</div>
</div>
<hr />
<div class='creator'>
<div class='wrapper'>
<img src={e.profileImg} alt="Creator" />
</div>
<p><ins>Creation of</ins><span className='text-white'> NF</span> </p>
</div>
</div>
</div>
</div>
</motion.div>
);})}
</motion.div>
</motion.div>
</div>
</div>
</div>
)
}
export default CardCaousel

React Hamburger Menu

I am new to react and still just grasping some of the concepts. I am trying to add a hamburger menu component, which adds fine, but I am confused about how to add a menu to the hamburger component itself.
Here is the code
render() {
const [isOpen, setOpen] = useState(false);
const {
installationsSection,
selectedInstallationIndex,
} = this.state;
return (
<div className="apollo-premier">
<Helmet>
<title>Apollo Premier</title>
<meta property="og:title" content="Apollo Premier" />
</Helmet>
{this.renderHeader(true)}
{this.renderHeader(false)}
<div className="content">
<div className="hero-container">
<img className="background" src={PremierHeroBackgroundAnimated} />
<img className="paint-background" src={PremierHeroPaint} />
<div className="text">
<p className="large">Breakthrough technology meets high-end design</p>
<div className="divider"><div></div></div>
<p>Apollo Premier is an elevated patent protected digital display for those who want to introduce the finest digital art into their home or business.</p>
<p>Apollo Premier houses your digital motion art collection to bring digital into a physical environment to enjoy your digital library.</p>
<p>A superior display experience, completely customized to each space and integrates seamlessly into smart home technology.</p>
</div>
</div>
<div className="section flex center the-process-section">
<div className="left">
<h2>The Process</h2>
<p>This customization process gives you complete control of the layout, functionality, and design of your Premier Display inside your space. We take you through the concept and implementation of each build meticulously from start to finish.</p>
<p>An array of material and layout options are available to select from to create an authentic and unique installation each and every time. The exclusive finishing touches, including lighting, music, power, and framing, can be customized for each setting.</p>
<div className="cta yellow">Inquire within</div>
</div>
<div className="right">
{/* <div className="the-process-steps">
<div className="the-process-step">
<img src="http://placehold.it/160x160" />
<p>Lorem ipsum dolor sit amet, consectetur</p>
</div>
<div className="the-process-step">
<img src="http://placehold.it/160x160" />
<p>Lorem ipsum dolor sit amet, consectetur</p>
</div>
<div className="the-process-step">
<img src="http://placehold.it/160x160" />
<p>Lorem ipsum dolor sit amet, consectetur</p>
</div>
<div className="the-process-step">
<img src="http://placehold.it/160x160" />
<p>Lorem ipsum dolor sit amet, consectetur</p>
</div>
</div> */}
<div className="the-process-placeholders">
<img src={PremierProcessPlaceholder1} />
<img src={PremierProcessPlaceholder2} />
</div>
</div>
</div>
<section className="section center installations">
{installationsSection && installationsSection.installations && <React.Fragment>
<h2>Customize</h2>
<p>Apollo Premier displays are completely bespoke and designed by in-house teams of architects for the most discerning homes and spaces.</p>
<Carousel
className="installations-carousel"
showThumbs={false}
showStatus={false}
showArrows={false}
swipeable={true}
selectedItem={selectedInstallationIndex}
onChange={this.updateSelectedInstallation}
>
{installationsSection.installations.map((installation, i) => <PremierInstallationItem key={i} installation={installation} />)}
</Carousel>
</React.Fragment>}
</section>
<div className="hero-container premier-plus">
<img className="background" src={PremierPlusBackground} />
<img className="paint-background" src={PremierPlusPaint} />
<div className="text">
<img src={ApolloPremierPlusLogo} alt="Apollo Premier Plus" />
<p className="inverted">Apollo Premier+ is the art lover's membership you have been waiting for, packed with exclusive access to events, fairs, artists and their work. A community with like minded individuals passionate about contemporary art.</p>
<div className="cta blue">Inquire for more information</div>
</div>
</div>
<div className="section center membership-benefits">
<h2>Membership<br />Benefits</h2>
<div className="divider"><div></div></div>
<div className="benefits-container">
<div>
<p className="title">Community</p>
<p className="sub-title">Events</p>
<p className="text">Members will enjoy access to prestigious events and member only programming</p>
</div>
<div>
<p className="title">Access</p>
<p className="sub-title">Unleashed Buying Power</p>
<p className="text">Members will have a 24 hour preview window of new digital NFT work before anyone else. </p>
</div>
<div>
<p className="title">Connection</p>
<p className="sub-title">Networking</p>
<p className="text">Meet like minded individuals that can lead to life-changing collaborations and relationships.</p>
</div>
</div>
</div>
</div>
<div className="intro-footer">
<div className="logo">
<img src={ApolloLogo} />
</div>
<p></p>
<p></p>
<p>
215 W. Huron Suite 1
<br />
Chicago, IL 60554
</p>
</div>
{installationsSection && installationsSection.installations && installationsSection.installations.map((installation, i) => <InstallationItemPopup key={i} installation={installation} />)}
</div>
);
}
renderHeader = (fixed: boolean) => {
return (
<div className={'header' + (fixed ? ' fixed' : '')}>
<div className="pencil-banner">
<div className="apollo-logo"><img src={ApolloLogoBlack} alt="Apollo" /></div>
<div className="concierge">
{/* <img src={IconSupportBlack} /> <span>Concierge</span> */}
</div>
<div className="contact">
<span>+1-877-790-1411</span> <span className="divider">|</span> Contact
</div>
</div>
<div className="nav">
<div className="logo">
<img src={ApolloPremierLogo} alt="Apollo Premier" />
</div>
<div className="nav-links">
<Hamburger toggled={isOpen} toggle={setOpen}>
Apollo App
Apollo Art
Apollo Premier
</Hamburger>
<div>
</div>
</div>
</div>
</div>
);
}
}
Hamburger is obviously where the menu is created.
But I am unable to get a drop down of the links:
I get a hooks error when I try the above code
render() {
const [isOpen, setOpen] = useState(false);
^ Since you're defining a render() method, it means you have a class component. Hooks (like useState) are supposed to be used from within function components.
You don't need hooks in class component, you can simply use this.setState() method to update state and life cycle methods in place of other hooks.

tailwind css responsive grid issue

I got issue when trying to add a "screen" prefix to grid-column, the layout is perfect but when I add md: to grid-col-span-6 everything is messed up.
this is the code :
import React from "react";
import app from "../images/app.png";
const Featured = () => {
return (
<div className="mt-52 ">
<h1 className="text-primary-dark-theme text-5xl mt-14">Projects</h1>
<div className="grid grid-cols-12 grid-rows-1 mt-20 ">
<div className="row-start-1 row-span-1 col-start-1 md:col-span-6">
<img src={app} alt="" className="w-full" />
</div>
<div className="row-start-1 row-span-1 col-start-6 col-span-7">
<div className="h-full w-full">
<h1 className="text-right text-primary-dark-theme">
Featured Project
</h1>
<h1 className="text-right text-gray-300 font-bold ">Title</h1>
<p className="p-5 bg-gray-800 text-gray-400 shadow-lg rounded-md mt-5">
Lorem ipsum dolor sit, amet consectetur adipisicing elit. Optio id
doloribus sequi repellendus aperiam dolore!
</p>
</div>
</div>
</div>
</div>
);
};
export default Featured;
This is how the ui looks in md
this is the result i want to have
this what happened when i add md predix to col-span-6
The issue seems to be that when applying the responsive md:col-span-6 it also overrides col-start-1 (you can see the styles no longer applied in the dev tools). Adding md:col-start-1 seems to fix this behaviour.
However, simply changing your image's wrapper <div /> to:
<div class="row-start-1 row-span-1 col-start-1 col-span-12">
Seems to have the desired result.

Warning: Received `true` for a non-boolean attribute `uk-grid`

I'm pretty new to React and getting this error when trying to use a https://getuikit.com/docs/card uikit card as a component.
Removing the attribute completely ruins the structure of the cards.
import React from 'react';
import faker from 'faker';
import "./css/Cards.css";
const Cards = (props) => {
return (
<div className="uk-card uk-card-default uk-width-1-2#m">
<div className="uk-card-header">
<div className="uk-grid-small uk-flex-middle" uk-grid>
<div className="uk-width-auto">
<img className="uk-border-circle" width="40" height="40" src={faker.image.animals} />>
</div>
<div className="uk-width-expand">
<h3 className="uk-card-title uk-margin-remove-bottom">Title</h3>
<p className="uk-text-meta uk-margin-remove-top"></p>
</div>
</div>
</div>
<div className="uk-card-body">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt.</p>
</div>
<div className="uk-card-footer">
Read more
</div>
</div>
)
}
export default Cards;
Thanks in advance!
According to the docs at https://getuikit.com/docs/javascript#component-usage when using with React you must prefix the attributes with data-.
So, instead of:
<div className="uk-grid-small uk-flex-middle" uk-grid>
Try:
<div className="uk-grid-small uk-flex-middle" data-uk-grid>

Resources