lambda-packages icon indicating copy to clipboard operation
lambda-packages copied to clipboard

Invalid Hook Call in React

Open cameronmcefee opened this issue 3 years ago • 16 comments

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.

cameronmcefee avatar Aug 09 '22 20:08 cameronmcefee

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>; };

Mrahmani71 avatar Aug 09 '22 21:08 Mrahmani71

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 avatar Aug 09 '22 22:08 FredKSchott

@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 avatar Aug 09 '22 22:08 FredKSchott

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

ShivamJoker avatar Aug 10 '22 15:08 ShivamJoker

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() { /*...*/ }

hippotastic avatar Aug 10 '22 19:08 hippotastic

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

joshuaiz avatar Aug 12 '22 19:08 joshuaiz

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

ptrkvsky avatar Aug 17 '22 05:08 ptrkvsky

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.

David-Huson avatar Aug 18 '22 19:08 David-Huson

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?

JeffMusgrave avatar Aug 19 '22 16:08 JeffMusgrave

same here, but

export default function SomeComponent(){}

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

rndy28 avatar Aug 20 '22 05:08 rndy28

My console is once again at peace. Thank you.

cameronmcefee avatar Aug 23 '22 21:08 cameronmcefee

Yes thank you. Sigh.

joshuaiz avatar Aug 24 '22 02:08 joshuaiz

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

miklschmidt avatar Sep 02 '22 13:09 miklschmidt

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

DevRSC avatar Sep 03 '22 14:09 DevRSC

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

bluwy avatar Sep 04 '22 08:09 bluwy