Git Product home page Git Product logo

react-hydration-on-demand's People

Contributors

dependabot[bot] avatar redabacha avatar valcol avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

react-hydration-on-demand's Issues

[Question] keyboard focus

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!

Component always hydrates after render of the withHydrationOnDemand component

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:

  1. App mounts
  2. LazyFooter renders
  3. inside WithHydrationOnDemand, isHydrated state is initially set to false
  4. Thus, the "Placeholder" compnent gets rendered. Note: this removes the data-hydration-on-demand="true" attribute from the placeholder
  5. useLayoutEffect gets executed
  6. wasRenderedServerSide is set to false, since the data-hydration-on-demand="true" attribute is not present anymore
  7. hydrate() gets called
  8. this causes the Footer component to mount on the next render, since hydrate() sets isHydrated to true

So, the issue seems to be that data-hydration-on-demand="true" gets removed on the first render.

React 18 peer dependencies

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?

Error on Readme

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 ;)

Render twice with React v18

When using this package with React v18, it renders the page twice. Checked on Mac - Google Chrome and Safari.

withHydrationOnDemand add tag section

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?

Display inline-block

Hello,

Why you add style display: inline-block on section ?
You should use a display: inherit to avoid breaking the existing style (:

image

Thank.

Que: does this work with React 18

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?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.