valcol / react-hydration-on-demand Goto Github PK
View Code? Open in Web Editor NEWHydrate your React components only when you need to.
License: MIT License
Hydrate your React components only when you need to.
License: MIT License
When using this package with React v18, it renders the page twice. Checked on Mac - Google Chrome and Safari.
I'm trying to use react-hydration-on-demand to load components on demand, but it seems to be adding an additional section wrapper around my component. I've tried setting the wrapper option to false in the withHydrationOnDemand HOC, but that doesn't seem to be working.
Here's an example of my withCustomWrapper HOC:
import withHydrationOnDemand from 'react-hydration-on-demand'
const MyCustomWrapper = ({ children }) => <>{children}</>
const withCustomWrapper = (Component, on = ['visible']) => {
const WrappedComponent = withHydrationOnDemand({ on, onBefore: Component.preload, wrapper: false })(Component)
return props => <MyCustomWrapper><WrappedComponent {...props} /></MyCustomWrapper>
}
export default withCustomWrapper
const ImageLazy = LoadableVisibility({ loader: () => import(/* webpackChunkName: "Image" */ './Image'), loading, wrapper: false })
const Image = withCustomWrapper(ImageLazy)
However, the resulting markup for the LazyImage component is:
<section>
<img src="https://example.com/image.jpg" />
</section>
Is there any way to use react-hydration-on-demand without adding this additional section wrapper?
I'm having an issue with this library, but I'm not quite sure if I'm missing something.
If the parent component is a chunk using code-splitting(@loadable/component), then it hydrates to empty html which ultimately leads to rendering of component on client side.
I forked your codesandbox to reproduce the issue:
https://codesandbox.io/s/react-hydration-on-demand-issue-13-forked-47xrw
Hello,
There is an error on the readme in the section on onBefore.
Component Card
is undefined. It must be replaced by LoadableCard.
import withHydrationOnDemand from "react-hydration-on-demand";
import loadable from "@loadable/component";
const LoadableCard = loadable(() => import("../Card"));
const CardWithHydrationOnDemand = withHydrationOnDemand({
on: ["visible"],
onBefore: LoadableCard.load
})(Card); // Error. It's LoadableCard !
You're welcome ;)
I would like to know if I could use this library on a page that uses SSG to get the information from an external API. Is that possible?
I'm having an issue with this library, but I'm not quite sure if I'm missing something.
I have roughly the following setup (simplified):
// App.jsx
import React, { useState, useEffect } from "react";
import withHydrationOnDemand from "react-hydration-on-demand";
import { Footer } from "./footer";
// also tried with options like { on: ["visible"]} etc...
// note: this should never hydrate on the client, and only be rendered once statically during SSR -> So displayed text in Footer should always be "Is not mounted (hydration pending)"
const LazyFooter = withHydrationOnDemand()(Footer);
const App = () => {
console.log('Render App');
const [someState, setSomeState] = useState(0);
// some logic that causes the component to render/execute multiple times
useEffect(() => {
const interval = setInterval(() => {
setSomeState((s) => s + 1);
}, 1000);
return () => clearInterval(interval);
}, [])
return (
<div>
<div style={{ height: "200vh" }}>
Some content {someState}
</div>
<LazyFooter />
</div>
);
};
// footer.jsx
import React, { useState, useEffect } from "react";
const Footer = () => {
// this should only execute on the client side, once this component has been hydrated
console.log('Render Footer');
const [isMounted, setIsMounted] = useState(false);
useEffect(() => {
setIsMounted(true);
}, [])
return (
<div className="footer">
{isMounted ? "Is Mounted" : "Is not mounted (hydration pending)"}
</div>
);
};
export {Footer};
When I now build my app using SSR, the outputted HTML contains the fully rendered component as expected, also with the data-hydration-on-demand="true"
attribute:
<div>
<div style="height: 200vh">
Some content 0
</div>
<section data-hydration-on-demand="true">
<div class="footer">
Is not mounted (hydration pending)
</div>
</section>
</div>
However, if I then open the app in my browser, the footer component gets hydrated immediately after mounting of the app. I can confirm this by the console output (see console.log above) as well as looking at the rendered text in the footer. The HTML of my App after mount then looks something like this:
<div>
<div style="height: 200vh">
Some content 2
</div>
<section>
<div class="footer">
Is Mounted
</div>
</section>
</div>
Investigating this a bit, I observed tho following happening, leading to this bug:
isHydrated
state is initially set to falsedata-hydration-on-demand="true"
attribute from the placeholderuseLayoutEffect
gets executeddata-hydration-on-demand="true"
attribute is not present anymorehydrate()
gets calledFooter
component to mount on the next render, since hydrate()
sets isHydrated
to trueSo, the issue seems to be that data-hydration-on-demand="true"
gets removed on the first render.
How can I trigger hydration by a specify promise?
Won't this code render empty html?
<section
ref={rootRef}
dangerouslySetInnerHTML={{ __html: "" }}
suppressHydrationWarning
{...wrapperProps}
/>
React 18 is strict about client and server mismatch during hydration so just wondering does this work with React 18 currenty?
If not, is there a plan to add react 18 support?
Hello, thank you for this great library!
If i add "focus" event to the component, then after hydration focus will reset.
Is it possible to focus on element after hydration?
Thanks!
If this works with React 18, could you update the peer dependencies section of its package.json so an app that uses it doesn't get peer dependency warnings?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.