React: .currentDispatcher gets set to null when calling ReactDOMServer from ReactDOM

Created on 29 Oct 2018  路  8Comments  路  Source: facebook/react

I happened to notice that React will throw Hooks can only be called inside the body of a function component if a sibling element calls ReactDOMServer.renderToStaticMarkup. I have a fiddle that shows this behavior (I think you need to manually open your console to see the error).

If you wrap the sibling element in a component or even just assign it a variable, this issue does not occur.

It's easy to get around and is a pretty specific bug, but why might this be happening?

Hooks Needs Investigation

Most helpful comment

Hey everybody!

Still same error!

I upgraded react, react-dom, react-apollo and everything else to latest yesterday

Then I decided to try useState again and...

As soon as I do SSR hydrate in production it breaks

SSR load works 100% a-okay, and as soon as we hydrate we get a blank page and invariant violation

This is has been happening for months now!

And this issue is already referenced from #13972

I cannot believe it is so edge-case that we cannot fix it??

All 8 comments

This happens because when renderToStaticMarkup exits, it sets currentDispatcher to null in the shared React package:

https://github.com/facebook/react/blob/169f935f781c764a8c04f441c5e27b00a0329e8c/packages/react-dom/src/server/ReactPartialRenderer.js#L868

Instead of setting it to its previous value. (ReactFiberScheduler does the same.)

That means that when you call useState in the child component, there is no dispatcher present.

@acdlite Thoughts? Should we restore the old value?

I think we should since it's a legit (even if not recommended) use case to call e.g. renderToStaticMarkup inside a component. At least it has been so far.

For those of you using next.js, the issue was resolved for me (temporarily) by just dropping the custom distDir I had set up in my next.config.js and reverting to .next for my dist

Is there a simple way to know if a particular commit has been added to a certain React version? I'm using 16.7.0-alpha.2 and as far as I can tell this fix is not part of that release, but I didn't find an easy way to check this. Thanks for any pointers!

Hey guys!

Still having this error - I think it's this! - on [email protected], SSR, and [email protected]

SSR works fine and the error throws on React.hydrate

Also I am using [email protected]

Here is my index.js

// @flow
/* eslint-disable react/jsx-max-depth */

import "intersection-observer"
import { ApolloProvider } from "react-apollo"
import App from "./app"
import { AppContainer } from "react-hot-loader"
import { BrowserRouter } from "react-router-dom"
import Loadable from "react-loadable"
import React from "react"
import ReactDOM from "react-dom"
import graphql from "api"

const app = document.getElementById("app")

const shell = Component => (
  <ApolloProvider client={graphql}>
    <AppContainer>
      <BrowserRouter>
        <Component />
      </BrowserRouter>
    </AppContainer>
  </ApolloProvider>
)

const render = Component => {
  if (app !== null) {
    // eslint-disable-next-line no-process-env
    if (process.env.NODE_ENV === "development") {
      ReactDOM.render(shell(Component), app)
    } else {
      Loadable.preloadReady().then(() => {
        ReactDOM.hydrate(shell(Component), app)
      })
    }
  }
}

render(App)

// Webpack Hot Module Replacement API
if (module.hot) {
  module.hot.accept("./app", () => {
    // eslint-disable-next-line global-require
    render(require("./app").default)
  })
}

Is anybody else having a similar problem? :smile:

Hey everybody!

Still same error!

I upgraded react, react-dom, react-apollo and everything else to latest yesterday

Then I decided to try useState again and...

As soon as I do SSR hydrate in production it breaks

SSR load works 100% a-okay, and as soon as we hydrate we get a blank page and invariant violation

This is has been happening for months now!

And this issue is already referenced from #13972

I cannot believe it is so edge-case that we cannot fix it??

Hey everybody!

Still same error!

I upgraded react, react-dom, react-apollo and everything else to latest yesterday

Then I decided to try useState again and...

As soon as I do SSR hydrate in production it breaks

SSR load works 100% a-okay, and as soon as we hydrate we get a blank page and invariant violation

This is has been happening for months now!

And this issue is already referenced from #13972

I cannot believe it is so edge-case that we cannot fix it??

@edoardo-bluframe How have you managed to work around this?

@joaquindk Totally not!

Cannot use hooks on an Apollo SSR project

Really nobody wants to fix it??

Was this page helpful?
0 / 5 - 0 ratings