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

[React Hooks] Webpack transpiled component throws invariant during SSR #13972

Closed
pheuter opened this issue Oct 25, 2018 · 28 comments
Closed

[React Hooks] Webpack transpiled component throws invariant during SSR #13972

pheuter opened this issue Oct 25, 2018 · 28 comments

Comments

@pheuter
Copy link

pheuter commented Oct 25, 2018

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); } })));
}
@hilkeheremans
Copy link

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

@pheuter
Copy link
Author

pheuter commented Oct 25, 2018

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;

@hilkeheremans
Copy link

hilkeheremans commented Oct 25, 2018

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.

@pheuter
Copy link
Author

pheuter commented Oct 25, 2018

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

@hilkeheremans
Copy link

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..

@pheuter
Copy link
Author

pheuter commented Oct 25, 2018

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

@pheuter pheuter changed the title [React Hooks] Webpack transpiled component throws invariant [React Hooks] Webpack transpiled component throws invariant during SSR Oct 25, 2018
@pheuter
Copy link
Author

pheuter commented Oct 25, 2018

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.

@hilkeheremans
Copy link

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

@aweary
Copy link
Contributor

aweary commented Oct 26, 2018

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

@dadamssg
Copy link

dadamssg commented Oct 26, 2018

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)

react@16.7.0-alpha.0
react-dom@16.7.0-alpha.0
webpack@4.22
react-hot-loader@4.3.11

@aweary
Copy link
Contributor

aweary commented Oct 26, 2018

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

@albinekb
Copy link

albinekb commented Oct 26, 2018

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?

@bkniffler
Copy link

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.

@pheuter
Copy link
Author

pheuter commented Oct 26, 2018

@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

@bkniffler
Copy link

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

@pheuter
Copy link
Author

pheuter commented Oct 26, 2018

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.

@pheuter
Copy link
Author

pheuter commented Oct 26, 2018

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

await getDataFromTree(<App />);

@theKashey
Copy link
Contributor

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.

@edorivai
Copy link

@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.

@victoryancn
Copy link

#14022

@gaearon
Copy link
Collaborator

gaearon commented Nov 1, 2018

Closing in favor of #14022.

@nassimbenkirane
Copy link

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)

@pheuter
Copy link
Author

pheuter commented Nov 15, 2018

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

@nassimbenkirane
Copy link

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

@seeden
Copy link

seeden commented Dec 15, 2018

It is still not working with latest versions :(

@yordis
Copy link

yordis commented Feb 20, 2019

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

@parker-codes
Copy link

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

@theKashey
Copy link
Contributor

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

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

No branches or pull requests