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 18: having Invalid hook call problem with rendering app wrapped by React.StrictMode #21848

Closed
julia-dizhak opened this issue Jul 12, 2021 · 10 comments
Labels
Resolution: Expected Behavior Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug

Comments

@julia-dizhak
Copy link

julia-dizhak commented Jul 12, 2021

I have a problem with rendering app after migrating to 18 version

const root = ReactDOM.createRoot(document.getElementById('root'));
const AppTest = () => <div>test react alpha 18</div>;
root.render(<React.StrictMode><App /></React.StrictMode>)

I have Invalid hook call warning in console
node is V14.16.1
installed react alpha via yarn add react@alpha react-dom@alpha

Dependencies

{
  "name": "frontend",
  "version": "1.7.0-0",
  "private": true,
  "scripts": {
    "start": "PORT=8080 ESLINT_NO_DEV_ERRORS=true TSC_COMPILE_ON_ERROR=true react-app-rewired start",
    "build": "ESLINT_NO_DEV_ERRORS=true TSC_COMPILE_ON_ERROR=true DISABLE_ESLINT_PLUGIN=true react-app-rewired build",
    "test": "NODE_ICU_DATA=node_modules/full-icu jest",
    "test:watch": "yarn test --watch",
    "test:coverage": "yarn test --collectCoverage",
    "test:coverage:develop": "yarn test:coverage --changedSince=origin/develop",
    "test:coverage:onlyChanged": "yarn test:coverage --onlyChanged",
    "translation-scan:ci": "i18next-scanner --config i18next-scanner.config.ci.js",
    "type": "tsc --noEmit",
    "type:ci": "tsc --noEmit --project tsconfig.ci.json",
    "type:watch": "tsc --noEmit -w",
    "prettier": "prettier --check --write \"**/*.{js,jsx,ts,tsx}\"",
    "lint": "eslint .",
    "lint:ci": "eslint -c .eslintrc-ci .",
    "lint:fix": "eslint --fix .",
    "lint:css": "stylelint './src/**/*.{js,jsx,ts,tsx}'",
    "stylelint-check": "stylelint-config-prettier-check",
    "storybook": "start-storybook -p 6006",
    "build-storybook": "build-storybook",
    "gql:codegen": "graphql-codegen --config src/types/graphql/codegen.yml",
    "chromatic": "yarn chromatic --project-token 10bde9e90fc3",
    "eject": "react-app-rewired eject"
  },
  "dependencies": {
    "@babel/helper-define-map": "7.13.12",
    "@date-io/moment": "2.10.11",
    "@material-ui/core": "4.11.2",
    "@material-ui/icons": "4.11.2",
    "@material-ui/lab": "4.0.0-alpha.57",
    "@material-ui/pickers": "3.2.10",
    "@material-ui/styles": "4.11.2",
    "@reduxjs/toolkit": "1.5.1",
    "@sentry/react": "6.2.1",
    "@sentry/tracing": "6.2.1",
    "@types/faker": "5.1.7",
    "@types/lodash": "4.14.170",
    "@types/react-helmet": "6.1.1",
    "@types/react-select": "4.0.13",
    "axios": "0.21.1",
    "babel-jest": "26.6.3",
    "camelcase": "6.2.0",
    "case-converter": "1.0.1",
    "chalk": "4.1.1",
    "clsx": "1.1.1",
    "core-js": "3.10.2",
    "data-forge": "1.8.17",
    "date-fns": "2.21.3",
    "expr-eval": "2.0.2",
    "faker": "5.4.0",
    "file-loader": "6.2.0",
    "file-selector": "0.2.4",
    "formik": "2.2.6",
    "full-icu": "1.3.1",
    "graphql": "15.5.0",
    "graphql-tag": "2.11.0",
    "history": "4.10.1",
    "husky": "3.1.0",
    "i18next": "19.9.2",
    "i18next-browser-languagedetector": "4.3.1",
    "i18next-http-backend": "1.2.1",
    "identity-obj-proxy": "3.0.0",
    "is-wsl": "1.1.0",
    "jest-resolve": "24.9.0",
    "jest-watch-typeahead": "0.6.1",
    "js-file-download": "0.4.12",
    "lodash": "4.17.21",
    "lodash.camelcase": "4.3.0",
    "lodash.find": "4.6.0",
    "lodash.findindex": "4.6.0",
    "lodash.get": "4.4.2",
    "lodash.groupby": "4.6.0",
    "lodash.includes": "4.3.0",
    "lodash.isequal": "4.5.0",
    "lodash.omit": "4.5.0",
    "logrocket": "1.0.14",
    "logrocket-react": "4.0.1",
    "mixpanel-browser": "2.41.0",
    "module-resolver": "1.0.0",
    "moment": "2.29.1",
    "moment-timezone": "0.5.33",
    "notistack": "1.0.9",
    "query-string": "6.14.1",
    "react": "^18.0.0-alpha-6bf111772-20210701",
    "react-app-polyfill": "2.0.0",
    "react-app-rewire-styled-components": "3.0.2",
    "react-country-flag": "2.3.0",
    "react-custom-scrollbars": "4.2.1",
    "react-data-grid": "7.0.0-canary.36",
    "react-datasheet": "1.4.9",
    "react-device-detect": "1.17.0",
    "react-dnd": "10.0.2",
    "react-dnd-html5-backend": "10.0.2",
    "react-dom": "^18.0.0-alpha-6bf111772-20210701",
    "react-dropzone": "11.3.2",
    "react-error-boundary": "3.1.1",
    "react-helmet": "6.1.0",
    "react-i18next": "11.8.13",
    "react-inlinesvg": "2.2.2",
    "react-query": "3.12.0",
    "react-redux": "7.2.2",
    "react-router": "5.2.0",
    "react-router-dom": "5.2.0",
    "react-scripts": "4.0.3",
    "react-select": "3.2.0",
    "react-select-event": "5.2.0",
    "react-table": "7.7.0",
    "react-use-intercom": "1.2.0",
    "react-window": "1.8.6",
    "recharts": "2.0.9",
    "redux": "4.0.5",
    "redux-devtools-extension": "2.13.9",
    "redux-form": "8.3.7",
    "redux-thunk": "2.3.0",
    "reselect": "4.0.0",
    "resolve": "1.20.0",
    "semver": "6.0.0",
    "snyk": "1.438.0",
    "socket.io-client": "2.4.0",
    "styled-components": "5.3.0",
    "throttle-debounce": "3.0.1",
    "ts-jest": "26.4.4",
    "ts-pnp": "1.1.2",
    "url-loader": "4.1.1",
    "use-query-params": "1.2.2",
    "uuid": "8.3.2",
    "xlsx": "0.17.0",
    "yup": "0.29.3"
  },
  "devDependencies": {
    "@babel/helper-define-map": "7.13.12",
    "@graphql-codegen/cli": "1.21.4",
    "@graphql-codegen/introspection": "1.18.2",
    "@graphql-codegen/typescript": "1.22.0",
    "@graphql-codegen/typescript-operations": "1.17.16",
    "@storybook/addon-actions": "6.2.9",
    "@storybook/addon-controls": "6.2.9",
    "@storybook/addon-essentials": "6.2.9",
    "@storybook/addon-links": "6.2.9",
    "@storybook/react": "6.2.9",
    "@testing-library/jest-dom": "5.12.0",
    "@testing-library/react": "11.2.7",
    "@testing-library/react-hooks": "7.0.0",
    "@types/gtag.js": "0.0.6",
    "@types/jest": "26.0.23",
    "@types/logrocket-react": "3.0.0",
    "@types/mixpanel-browser": "2.35.6",
    "@types/node": "14.14.44",
    "@types/papaparse": "5.2.5",
    "@types/react": "^17.0.13",
    "@types/react-dom": "^17.0.8",
    "@types/react-redux": "7.1.16",
    "@types/react-router-dom": "5.1.7",
    "@types/react-table": "7.7.1",
    "@types/react-window": "1.8.3",
    "@types/redux-form": "8.3.1",
    "@types/redux-mock-store": "1.0.2",
    "@types/styled-components": "5.1.7",
    "@types/uuid": "8.3.0",
    "@types/yup": "0.29.11",
    "@typescript-eslint/eslint-plugin": "4.15.0",
    "@typescript-eslint/parser": "4.15.0",
    "axios-mock-adapter": "1.19.0",
    "chromatic": "5.9.2",
    "circular-dependency-plugin": "5.2.2",
    "customize-cra": "1.0.0",
    "esbuild": "0.12.12",
    "esbuild-loader": "2.13.1",
    "eslint": "7.19.0",
    "eslint-config-airbnb": "18.2.1",
    "eslint-config-prettier": "6.15.0",
    "eslint-import-resolver-babel-module": "5.3.1",
    "eslint-import-resolver-typescript": "2.4.0",
    "eslint-plugin-fp": "2.3.0",
    "eslint-plugin-import": "2.23.4",
    "eslint-plugin-jest": "24.3.6",
    "eslint-plugin-jsx-a11y": "6.4.1",
    "eslint-plugin-prettier": "3.4.0",
    "eslint-plugin-react": "7.24.0",
    "eslint-plugin-react-hooks": "4.2.0",
    "eslint-plugin-testing-library": "4.6.0",
    "http-proxy-middleware": "1.0.6",
    "i18next-scanner": "2.11.0",
    "i18next-scanner-typescript": "1.0.6",
    "jest-junit": "12.2.0",
    "jest-styled-components": "^7.0.4",
    "jest-svg-transformer": "1.0.0",
    "lint-staged": "11.0.0",
    "prettier": "2.2.1",
    "prop-types": "15.7.2",
    "react-app-rewire-alias": "1.0.2",
    "react-app-rewired": "2.1.8",
    "react-is": "17.0.1",
    "redux-mock-store": "1.5.4",
    "strip-json-comments": "3.1.1",
    "stylelint": "13.12.0",
    "stylelint-config-prettier": "8.0.2",
    "stylelint-config-recommended": "3.0.0",
    "stylelint-config-standard": "18.3.0",
    "stylelint-config-styled-components": "0.1.1",
    "stylelint-processor-styled-components": "1.10.0",
    "typescript": "3.9.7"
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all",
      "ie 11"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version",
      "ie 11"
    ]
  },
  "resolutions": {
    "babel-loader": "8.1.0",
    "**/recharts-scale": "0.4.2"
  },
  "babel": {
    "presets": [
      "react-app"
    ]
  },
  "husky": {
    "hooks": {
      "pre-commit": "yarn lint-staged"
    }
  },
  "snyk": true
}

https://codesandbox.io/s/new

@julia-dizhak julia-dizhak added React 18 Bug reports, questions, and general feedback about React 18 Type: Discussion labels Jul 12, 2021
@eps1lon
Copy link
Collaborator

eps1lon commented Jul 12, 2021

Thanks for the feedback.

I suspect that your package manager installed both React 18 and 17. Multiple React versions is one of the reasons for the "invalid hook call" error message.

This might be due to dependencies requiring React 17 via peer dependencies.

What package manager are you using?

@bvaughn bvaughn added Resolution: Needs More Information and removed React 18 Bug reports, questions, and general feedback about React 18 Type: Discussion labels Jul 12, 2021
@bvaughn
Copy link
Contributor

bvaughn commented Jul 12, 2021

Hi @julia-dizhak 👋

Can you help us by providing a link to a CodeSandbox (https://codesandbox.io/s/new), a repository on GitHub, or a minimal code example that reproduces the problem? The info provided isn't sufficient to rule out something like what @eps1lon mentions above.

@julia-dizhak
Copy link
Author

julia-dizhak commented Jul 12, 2021

hi @bvaughn thanks for taking care
here is the sandbox https://codesandbox.io/s/b52q1

React_18_-_CodeSandbox

@julia-dizhak
Copy link
Author

Thanks for the feedback.

I suspect that your package manager installed both React 18 and 17. Multiple React versions is one of the reasons for the "invalid hook call" error message.

This might be due to dependencies requiring React 17 via peer dependencies.

What package manager are you using?

hi @eps1lon thanks for support
I installed react alpha via yarn add react@alpha react-dom@alpha, node is V14.16.1
As well I deleted node-modules and re-installed peer dependencies

@bvaughn bvaughn added Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug and removed Resolution: Needs More Information labels Jul 12, 2021
@bvaughn
Copy link
Contributor

bvaughn commented Jul 12, 2021

Thanks for the repro!

@eps1lon
Copy link
Collaborator

eps1lon commented Jul 12, 2021

hi @bvaughn thanks for taking care
here is the sandbox codesandbox.io/s/b52q1

That looks like it's caused by a dev-only logic from styled-components (styled-components/styled-components#3394, styled-components/styled-components#3409) since the reported issue is already reproducible with

import styled from "styled-components";

const StyledPeopleIcon = styled("svg")`
  margin: 10px;
`;

Closing since it's caused by a 3rd party library. The issue is already fixed in styled-components/styled-components#3521 but not released yet.

@gaearon
Copy link
Collaborator

gaearon commented Jul 12, 2021

Hmm, wait, something isn't right here.

The comments in styled-components/styled-components#3521 claim:

    // If a hook is called outside of a component:
    // React 17 and earlier throw an error
    // React 18 and above use console.error

I don't remember a change like this. I expect we still have a production invariant/error in cases of invalid Hook call.

Can we investigate what the difference is?

@gaearon gaearon reopened this Jul 12, 2021
@gaearon
Copy link
Collaborator

gaearon commented Jul 12, 2021

We throw here:

invariant(
false,
'Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for' +
' one of the following reasons:\n' +
'1. You might have mismatching versions of React and the renderer (such as React DOM)\n' +
'2. You might be breaking the Rules of Hooks\n' +
'3. You might have more than one copy of React in the same app\n' +
'See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.',
);

There is a DEV-only console.error here:

if (__DEV__) {
if (dispatcher === null) {
console.error(
'Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for' +
' one of the following reasons:\n' +
'1. You might have mismatching versions of React and the renderer (such as React DOM)\n' +
'2. You might be breaking the Rules of Hooks\n' +
'3. You might have more than one copy of React in the same app\n' +
'See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.',
);
}
}
// Will result in a null access error if accessed outside render phase. We
// intentionally don't throw our own error because this is in a hot path.
// Also helps ensure this is inlined.

But it's supposed to throw right afterwards with null access (essentially, null.useState).

Are you saying it doesn't throw anymore?

@eps1lon
Copy link
Collaborator

eps1lon commented Jul 12, 2021

I don't remember a change like this. I expect we still have a production invariant/error in cases of invalid Hook call.

I'm pretty sure this was changed in #20604 since I saw the errors shortly after in integration tests with react@next.

Are you saying it doesn't throw anymore?

It does throw but it's no longer clear why without also listening to the console. So the claim is a bit incomplete but sufficient for what we're trying to do: Checking if we're called from inside a function component requires different implementations for React 17 and 18 due to #20604

@gaearon
Copy link
Collaborator

gaearon commented Jul 12, 2021

Ah ok.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Resolution: Expected Behavior Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug
Projects
None yet
Development

No branches or pull requests

4 participants