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

Invalid Hook Call in React #4220

Closed
1 task
cameronmcefee opened this issue Aug 9, 2022 · 16 comments · Fixed by #4385 or #4831
Closed
1 task

Invalid Hook Call in React #4220

cameronmcefee opened this issue Aug 9, 2022 · 16 comments · Fixed by #4385 or #4831
Assignees
Labels
- P4: important Violate documented behavior or significantly impacts performance (priority) pkg: preact Related to Preact (scope) pkg: react Related to React (scope)

Comments

@cameronmcefee
Copy link
Contributor

cameronmcefee commented Aug 9, 2022

What version of astro are you using?

1.0.0

Are you using an SSR adapter? If so, which one?

None

What package manager are you using?

yarn

What operating system are you using?

Mac

Describe the Bug

When running my site with the React plugin in development, I see InvalidHookCall warnings. In the repro, run:

yarn
yarn start

When you load http://localhost:3000/ you'll se the error in the terminal output.

The error only exists when using a hook, and given the simple usage, I'm confident the use is accurate. Thus, my assumption is that the cause is a mismatch in versions of React as cited in the third possibility of the message.

3. You might have more than one copy of React in the same app

With my spelunking in #4084 I know that Astro uses a custom renderer, so I suspect the issues lies therein somewhere. As further evidence of my suspicion, in the official docs for this issue they recommend the following:

// Add this in node_modules/react-dom/index.js
window.React1 = require('react');

While this example obviously fails in SSR, if you do something simple like just logging "hello world" from that file, I see the log in the terminal (presumably for SSR) but not in the browser console, so I'm guessing react-dom is not used during hydration.

Link to Minimal Reproducible Example

https://github.com/cameronmcefee/invalid-hook-call-example

Participation

  • I am willing to submit a pull request for this issue.
@Mrahmani71
Copy link

I had the same problem, I fix it like this:

## Incorrect
function Nav(){}
export default Nav;

## Incorrect
const Nav = () => {}
export default Nav;


## Correct
export default function Nav(){}

I think, you need to change your component.tsx, like this

export default function Component() { const [test, setTest] = useState(true); return <p>Hello world</p>; };

@FredKSchott
Copy link
Member

I can reproduce this as well, however I only see one copy of react in your node_modules folder:
Screen Shot 2022-08-09 at 3 34 26 PM

@Mrahmani71 that also fixes it for me, which is wild! @natemoo-re anything odd that our JSX compilation step could be doing?

@FredKSchott
Copy link
Member

@natemoo-re and I tracked this down to packages/astro/src/vite-plugin-jsx/tag.ts not understanding anything other than export default function X and export function X. If anyone likes working with Babel, this would be a fun PR to add an understanding of export { X} and export const X and export default const X!

@FredKSchott FredKSchott added - P4: important Violate documented behavior or significantly impacts performance (priority) pkg: react Related to React (scope) pkg: preact Related to Preact (scope) s1-small labels Aug 9, 2022
@ShivamJoker
Copy link
Contributor

Hey Astro team I am also facing the same while using some basic hooks it will be great to get this fixes in coming days

@hippotastic
Copy link
Contributor

I also just encountered this issue. In addition to what was already reported here, I have found the following:

// ❌ Exporting an anonymous function causes the warning to be logged
export default function () { /*...*/ }

// ✅ Exporting a named function works well
export default function Counter() { /*...*/ }

@joshuaiz
Copy link

Seeing this as well. What is interesting in my case is after using --trace-warnings the trace indicates the error is coming from an .astro component which obviously cannot have any React hook calls (and it does not).

connorads added a commit to connorads/connoradams.co.uk that referenced this issue Aug 16, 2022
connorads added a commit to connorads/connoradams.co.uk that referenced this issue Aug 16, 2022
* Upgrade dependencies

* Workaround: Invalid hook call
withastro/astro#4220 (comment)

* Run prettier
@ptrkvsky
Copy link

ptrkvsky commented Aug 17, 2022

Screenshot from 2022-08-17 07-23-43
Same here
07:22:29 AM [astro] reload /src/hooks/useScrollSpy.tsx Warning: 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:
Screenshot from 2022-08-17 07-25-16

@David-Huson
Copy link

I'm also experiencing this error, using Astro version 1.0.0.

The error:

Warning: 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:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app

Ive done some trouble shooting and found that this error only occurs when using arrow functions.

This works with no invalid hook call error:

import { useState, useEffect } from 'react';
import { Sun, Moon } from 'react-feather';

export default function ThemeToggle() {
  const [darkTheme, setDarkTheme] = useState(false);
  useEffect(() => {
    const body = document.querySelector('body');
    if (darkTheme) {
      body?.classList.add('dark');
    } else {
      body?.classList.remove('dark');
    }
  }, [darkTheme]);
  return (
    <div className="cursor-pointer">
      <input
        type="checkbox"
        name="themeToggle"
        id="checkbox"
        className="hidden"
        defaultChecked
        onClick={() => {
          setDarkTheme;
        }}
      />
      <label
        htmlFor="checkbox"
        className="text-yellow-500 md:hidden md:dark:block"
      >
        {/* <Sun /> */}
        {darkTheme ? <Sun /> : <Moon />}
      </label>
    </div>
  );
}

This (arrow function equivalent) causes the invaild hook call error:

const ThemeToggle: FunctionComponent = () => {
  const [darkTheme, setDarkTheme] = useState(false);
  useEffect(() => {
    const body = document.querySelector('body');
    if (darkTheme) {
      body?.classList.add('dark');
    } else {
      body?.classList.remove('dark');
    }
  }, [darkTheme]);
  return (
    <div className="cursor-pointer">
      <input
        type="checkbox"
        name="themeToggle"
        id="checkbox"
        className="hidden"
        defaultChecked
        onClick={() => {
          setDarkTheme;
        }}
      />
      <label
        htmlFor="checkbox"
        className="text-yellow-500 md:hidden md:dark:block"
      >
        {darkTheme ? <Sun /> : <Moon />}
      </label>
    </div>
  );
}

What is really confusing for me is that the Astro docs use the above arrow function to achieve the functionality
See here: https://github.com/withastro/docs/blob/main/src/components/Header/ThemeToggleButton.tsx

Also, this error occurs when I deploy to Vercel (site gets built) and seems to be caused by a dependency from which I use a react component.
The dependency is called @portabletext/react and is used to parse Sanity CMS Portable Text (Block Content) to Markdown.

usage:

{post.body.map((block: any) => (
          (block._type == 'code') 
          ?
          <Code code={block.code} lang={block.language} theme={'github-dark'} />
          :
          <PortableText value={block} />
          // toMarkdown(block)
          ))}

the errors:

▶ src/pages/blog/[slug].astro

15:14:28.048 | Warning: 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:
15:14:28.048 | 1. You might have mismatching versions of React and the renderer (such as React DOM)
15:14:28.048 | 2. You might be breaking the Rules of Hooks
15:14:28.049 | 3. You might have more than one copy of React in the same app
15:14:28.049 | See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.
├─ /blog/my-first-post/index.html (+1.11s)

This error occurs for each call to the <PortableText /> component and does not occur when i remove this component.

@JeffMusgrave
Copy link

JeffMusgrave commented Aug 19, 2022

I am also getting this same issue when I try to use the component library Chakra-UI. I've tried both the strict TS settings and JS settings. Both throw the same warnings and won't render correctly.

Is there any ETA for a fix?

@rndy28
Copy link

rndy28 commented Aug 20, 2022

same here, but

export default function SomeComponent(){}

seems to fixed it. is there any progress regarding what causing the issue?

@cameronmcefee
Copy link
Contributor Author

My console is once again at peace. Thank you.

@joshuaiz
Copy link

Yes thank you. Sigh.

@miklschmidt
Copy link

Maybe this should be reopened since the fix was reverted, or is it tracked somewhere else?

@DevRSC
Copy link

DevRSC commented Sep 3, 2022

I still face this issue when using arrow functions. I hope they'll fix this issue

@bluwy
Copy link
Member

bluwy commented Sep 4, 2022

It doesn't look like there's a separate issue, or is fixed with a different PR. Re-opening.

@maxdevjs
Copy link

Experiencing this issue today

with a simple named function (not an arrow function)

The following code logs the warning message:

function Showcase() {
  const [name, setName] = useState('Name here')
  return <div>Hello { name }</div>
}

export default Showcase

The following code does not log the warning message:

export default function Showcase() {
  const [name, setName] = useState('Name here')
  return <div>Hello { name }</div>
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
- P4: important Violate documented behavior or significantly impacts performance (priority) pkg: preact Related to Preact (scope) pkg: react Related to React (scope)
Projects
None yet