Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Progressive hydration strategy with context #2

Open
aralroca opened this issue Aug 30, 2019 · 7 comments
Open

Progressive hydration strategy with context #2

aralroca opened this issue Aug 30, 2019 · 7 comments

Comments

@aralroca
Copy link

aralroca commented Aug 30, 2019

The progressive hydration strategy doesn't work well with react context, exactly in this scenario:

  1. Providing some context value on the top of the app.
  2. Consuming a context inside the children that is hydrated with the ProgressiveHydration component.
const Context = createContext()

function Content() {
  const value = useContext(Context)
  const [status, setStatus] = useState('not hydrated yet')

  useEffect(() => setStatus('hydrated'), [])

  return `status: ${status} - context value: ${value}`
}

function App() {
  return (
    <Context.Provider value="example">
      <ProgressiveHydration>
        <Content />
      </ProgressiveHydration>
    </Context.Provider>
  )
}

Result:

The context value is undefined after the rehydration...

Before hydration: status: not hydrated yet - context value: example
After hydration: status: hydrated - context value: undefined


I'm not sure if this can be solved in an easy way or there is some limitation on this strategy. Any idea @midudev ?

@aralroca aralroca reopened this Aug 31, 2019
@midudev
Copy link
Owner

midudev commented Sep 2, 2019

Interesting. Tricky but not impossible.

You could try to move the provider inside the ProgressiveHydration component instead. This should enable the context to be available inside the progressive hydrated content as well.

<ProgressiveHydration>
  <Context.Provider value="example">
     <Content />
  </Context.Provider>
</ProgressiveHydration

@aralroca
Copy link
Author

aralroca commented Sep 2, 2019

@midudev is not possible to share context values between Progressive hydration parts like, for example, for I18nProvider?:

I'm looking for something like:

<Layout>
  <I18nProvider>

   {/* FIRST PROGRESSIVE HYDRATION SECTION */}
    <ProgressiveHydration>
      <Section1 />
    </ProgressiveHydration>

   {/* SECOND PROGRESSIVE HYDRATION SECTION */}
    <ProgressiveHydration>
      <Section2 />
    </ProgressiveHydration>

  </I18nProvider>
</Layout>

Doing this, in this case, is not the solution:

<Layout>

   {/* FIRST PROGRESSIVE HYDRATION SECTION */}
  <ProgressiveHydration>
    <I18nProvider>
       <Section1 />
    </I18nProvider>
  </ProgressiveHydration>

  {/* SECOND PROGRESSIVE HYDRATION SECTION */}
  <ProgressiveHydration>
     <I18nProvider>
       <Section2 />
      </I18nProvider>
  </ProgressiveHydration>

</Layout>

Here we are duplicating the i18n context in each section.

So, is there that limitation doing the hydrate manually inside the ProgressiveHydration 😕?

@midudev
Copy link
Owner

midudev commented Sep 2, 2019

But, is the solution working? There's no problem duplicating the i18n context provider. In fact, using Context.Provider more than once could be typical for some cases.

As it's using internally hydrate it could be assuming is a different root and, thus, you need to provide the context. The problem would be if the Context has some kind of internal state that could be tricky... should work, but I'm not sure. :) Definitely should work correctly for read-only context.

@aralroca
Copy link
Author

aralroca commented Sep 3, 2019

It works in a read-only context as you said.

I've put before the example of I18nProvider custom provider but maybe is not so clear, my bad. In my case, I have more than one custom provider with their own state, maybe a better example is the CartProvider, when you can consume everywhere which product is already in the cart, etc. (as a redux store).

So duplicating these contexts mean duplicating different state instead of sharing the same.

@midudev
Copy link
Owner

midudev commented Sep 3, 2019

Yes, sadly, I would say is a limitation for the strategy as well. :( As you said, duplicating these contexts will create two states for it and thus won't share the same. I will investigate about this limitation in order to try some workaround but, for get this working, more likely some inside ReactDOM work should be done.

@Jeevan-Kishore
Copy link

@midudev The same seem to happen with connect function from react-redux in children, do we have a workaround for the same?

Error:

connectAdvanced.js?fe33:245 Uncaught Error: Could not find "store" in the context of "Connect(LinkBase)". Either wrap the root component in a <Provider>, or pass a custom React context provider to <Provider> and the corresponding React context consumer to Connect(LinkBase) in connect options.

@jee
Copy link

jee commented Jul 14, 2021

Thanks for the great react rendering strategies - I too am having the issues that @Jeevan-Kishore described above. I tried implementing the work-around that was described here:

GoogleChromeLabs/progressive-rendering-frameworks-samples#2 (comment)

Unfortunately, I was not successful.

@midudev - do you have any suggestions or have you experienced this issue with any of your apps? If so, how did you go about addressing them?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants