React: [React Hooks] Webpack transpiled component throws invariant during SSR

Created on 25 Oct 2018  路  28Comments  路  Source: facebook/react

What is the current behavior?

UnhandledPromiseRejectionWarning: Invariant Violation: Hooks can only be called inside the body of a function component.
        |     at invariant (webpack://%5Bname%5D_%5Bhash%5D/./node_modules/react/cjs/react.development.js?:125:15)
        |     at resolveDispatcher (webpack://%5Bname%5D_%5Bhash%5D/./node_modules/react/cjs/react.development.js?:1450:28)
        |     at useState (webpack://%5Bname%5D_%5Bhash%5D/./node_modules/react/cjs/react.development.js?:1473:20)

Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?
16.7.0-alpha.0


This is what the component looks like after it's transpiled by Webpack:

function HookedComponent() {
    var _a = Object(react__WEBPACK_IMPORTED_MODULE_1__["useState"])("Mary"), name = _a[0], setName = _a[1];
    return (react__WEBPACK_IMPORTED_MODULE_1__["createElement"]("div", null,
        react__WEBPACK_IMPORTED_MODULE_1__["createElement"]("h1", null, name),
        react__WEBPACK_IMPORTED_MODULE_1__["createElement"]("input", { value: name, onChange: function (e) { return setName(e.target.value); } })));
}
Needs More Information

Most helpful comment

Your code works fine here. You sure you are using both react and react-dom's latest alpha versions? I forgot to update react-dom initially which resulted in some oddish errors.

All 28 comments

Could you paste your original (untranspiled) code here as well?

import { useState } from "react";

function HookedComponent() {
  const [name, setName] = useState("Mary");

  return (
    <div>
      <h1>{name}</h1>
      <input value={name} onChange={e => setName(e.target.value)} />
    </div>
  );
}

export default HookedComponent;

Your code works fine here. You sure you are using both react and react-dom's latest alpha versions? I forgot to update react-dom initially which resulted in some oddish errors.

Both are on the alpha version. I suspect it might have something to do with how Webpack is transpiling it.

Maybe -- I should note I'm also running Webpack, but more indirectly using CRA 2.0 after manually upgrading the react and react-dom versions..

Perhaps also worth noting on my end that this error occurs during a server-side render call from react-dom/server/renderToString()

This is interesting because it works on the browser if I hot load the component in, but crashes the renderToString() call when it exists during a server-side render.

Well, that makes sense now... I can totally imagine that SSR support is not there yet.

Hooks should work with renderToString. @pheuter are you using Babel with Webpack? If so, what plugins are you using?

I've having this same issue but not using SSR. Literally copy/pasted the <Example /> counter component into my existing app. Here's the transpiled code.

function Example() {
  var _useState = Object(react__WEBPACK_IMPORTED_MODULE_1__["useState"])(0),
      _useState2 = Object(_babel_runtime_helpers_esm_slicedToArray__WEBPACK_IMPORTED_MODULE_0__["default"])(_useState, 2),
      count = _useState2[0],
      setCount = _useState2[1]; // Similar to componentDidMount and componentDidUpdate:


  Object(react__WEBPACK_IMPORTED_MODULE_1__["useEffect"])(function () {
    // Update the document title using the browser API
    document.title = "You clicked ".concat(count, " times");
  });
  return react__WEBPACK_IMPORTED_MODULE_1___default.a.createElement("div", null, react__WEBPACK_IMPORTED_MODULE_1___default.a.createElement("p", null, "You clicked ", count, " times"), react__WEBPACK_IMPORTED_MODULE_1___default.a.createElement("button", {
    onClick: function onClick() {
      return setCount(count + 1);
    }
  }, "Click me"));
}
react-dom.development.js:55 Uncaught Error: Hooks can only be called inside the body of a function component.
    at invariant (react-dom.development.js:55)
    at resolveCurrentlyRenderingFiber (react-dom.development.js:11510)
    at useReducer (react-dom.development.js:11707)
    at Object.useState (react-dom.development.js:11701)
    at useState (react.development.js:1474)
    at Example (MyComponent.js:25)
    at ProxyComponent.hotComponentRender (react-hot-loader.development.js:618)
    at ProxyComponent.proxiedRender (react-hot-loader.development.js:635)
    at finishClassComponent (react-dom.development.js:14343)
    at updateClassComponent (react-dom.development.js:14306)

[email protected]
[email protected]
[email protected]
[email protected]

@dadamssg do you get the same error if you remove react-hot-loader?

I got the same issue as @dadamssg yesterday, narrowed it down to being something that react-hot-loader does. Not sure about SSR parts. I think it's two different issues?

Can't say anything to SSR, but hot loader definitely doesn't work. When I replace the export default hot(module)(App); part of my app.js with export default App, the error goes away.

@aweary @bkniffler Removed react-hot-loader from my app and still getting the same error. Is it relevant that the source code is written in TypeScript and transpiled using ts-loader?

Edit: Not using Babel

Might be, I'm also using typescript, but through babel, and I'm not having issues after removing hot loader.

Switched over to using babel-loader, same invariant violation thrown when doing renderToString.

Should note that the same exact app works fine when I avoid rendering the function component on the server and only render it on the client.

Looks like it has something to do with rendering the app tree during react-apollo's getDataFromTree:

await getDataFromTree(<App />);

I am afraid, but hook would break any custom react-tree traversal:

  • apollo
  • react-hot-loader
  • loadable-components
  • async-component
  • and more and more and more.

@pheuter Having the exact same issue. Everything works on client, breaks on server. Using Typescript, babel (after ts-loader), webpack, react@next, react-dom@next.

@theKashey Ah that would make so much sense! Would be getDataFromTree in our case.

Hi @pheuter,
Do you still have the issue ? There is a merged PR that fixes #14022 but I don't know if it was released with 16.7.0-alpha.2
I'm still having the same issue as the original one : i.e. a webpack/babel transpiled component with hooks raising the Invariant Violation when using SSR (renderToString or renderToStaticMarkup)

@nassimbenkirane This issue was fixed earlier for me in a separate library that I was using, specifically getDataFromTree from react-apollo

Thanks for your answer :) I'm gonna have to find why it breaks

It is still not working with latest versions :(

For us was react-hot-loader using CRA like setup

Those using Parcel will need to update react-hot-loader.

For any react-hot-loader related issues please one an issue in RHL project.

Was this page helpful?
0 / 5 - 0 ratings