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

Bug: Internal React error: Expected static flag was missing #24391

Open
Developer-Nijat opened this issue Apr 17, 2022 · 23 comments
Open

Bug: Internal React error: Expected static flag was missing #24391

Developer-Nijat opened this issue Apr 17, 2022 · 23 comments
Labels
Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug Type: Bug

Comments

@Developer-Nijat
Copy link

React version: V18.0.0
React router DOM: V5.2.1

Steps To Reproduce

  1. Going to profile page
  2. Warning: Internal React error: Expected static flag was missing. Please notify the React team.

Link to code example:
Screenshot 2022-04-17 124859
DynamicFilter.js component
Screenshot 2022-04-17 125107

The current behavior

The expected behavior

@Developer-Nijat Developer-Nijat added the Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug label Apr 17, 2022
@gaearon
Copy link
Collaborator

gaearon commented Apr 17, 2022

Please provide a reproducible example. Either on GitHub or a sandbox. Otherwise we can’t really fix this. Thanks!

@Developer-Nijat
Copy link
Author

Please provide a reproducible example. Either on GitHub or a sandbox. Otherwise we can’t really fix this. Thanks!

Probably it is not possible. Because this is the large project and totally code sharing is prohibited. It is understandable, React v18 is not good for old projects.

@gaearon
Copy link
Collaborator

gaearon commented Apr 17, 2022

It is understandable, React v18 is not good for old projects.

That's absolutely not correct. We're running huge codebases from 2013-2014 with almost no changes on React 18. The error is just a bug in React that will be easy to fix as soon as somebody gives us a reproducible example.

Probably it is not possible. Because this is the large project and totally code sharing is prohibited.

Usually the way you can do this is by deleting code until you're left with a small example that doesn't contain any app-specific logic.

@orangecoding
Copy link

@gaearon Here's a small test repo, that will reproduce the bug.
https://github.com/orangecoding/react-static-flag-exception

@gaearon
Copy link
Collaborator

gaearon commented Apr 22, 2022

Thank you! This example seems to use a Hook conditionally — it (data) useStyles(). This is not supported in React. If you use Hooks you need to either follow rules or use the linter rule which forbids this.

@orangecoding
Copy link

Yeah I know this. Unfortunatelly lot's of ppl doesn't seem to know this and this is a common thing that I'm seeing throughout a lot of libs. I copied this particular issue from here: https://github.com/farahat80/react-open-weather/blob/master/src/js/components/ReactWeather.js#L20

Going back to react 17, these things work without any issues...

@gaearon
Copy link
Collaborator

gaearon commented Apr 22, 2022

It works accidentally and likely breaks in other cases. But we do need a better error. I would’ve expected “rendered more hooks than last time” error to appear.

@orangecoding
Copy link

orangecoding commented Apr 22, 2022

I fear that when this is going to be thrown as an error (which it actually is, no discussion here), a lot of external libs will be broken.
However not sure if this is the only case where such an error occurs. Maybe @Developer-Nijat can check this with his code as well?

@Developer-Nijat
Copy link
Author

I fear that when this is going to be thrown as an error (which it actually is, no discussion here), a lot of external libs will be broken.
However not sure if this is the only case where such an error occurs. Maybe @Developer-Nijat can check this with his code as well?

First of all, let's say this is not understandable error. We can't figure out where the error is. Again there is a high risk of errors in the next days. Currently v18 is risk for large projects. I will check this error again but

@firoz2580
Copy link

firoz2580 commented Apr 24, 2022

The issue is exactly as what @gaearon said.
In my case, the very first line of the component was checking a prop 'hidden' and returning a fragment if it is true.
That was causing this error. Though it was not a best practice, V17 was OK with this.

SidebarItem.tsx
Issue:
image

The fix was to do the check after initiating the hook.

Fix:
image

@eps1lon
Copy link
Collaborator

eps1lon commented Apr 24, 2022

Reproducible if an additional useEffect was called: https://codesandbox.io/s/conditional-useeffect-static-flag-was-missing-gg94qy

An additional useState will throw the expected "rendered more hooks than expected" error.

In React 17, no error is logged nor thrown: https://codesandbox.io/s/react-17-conditional-useeffect-static-flag-was-missing-forked-qbgm67

@gaearon
Copy link
Collaborator

gaearon commented Apr 24, 2022

Though it was not a best practice, V17 was OK with this.

I want to make it clear that it worked accidentally and in a narrow range of circumstances. You should absolutely not rely on this. For example, any person who adds state to the corresponding custom Hook would break every component relying on this even in 17.

I agree it’s a problem that the error is unclear and removed from the actual case. That has to be fixed.

But this has nothing to do with 18. If your code relies on this, it is extremely fragile in 17. Enable the linter and fix it.

@orangecoding
Copy link

Enable the linter and fix it.
As I said, I saw these things in at least 2 external debts (one of which is semantic-ui-react which has millions of downloads). So yeah, I agree it kinda has to be fixed by the vendor, however I guess this deserves some major communication efforts, coz otherwise ppl will most likely not update their libs (I guess)

@FabrizioArmango
Copy link

I had the same warning migrating from v17 to v18:

Before

const C = () =>  {
    if (condition) return null;
    useEffect(() => {/*...*/}, []);
    return <div></div>
}

After

const C = () =>  {
    useEffect(() => {/*...*/}, []);
    if (condition) return null;
    return <div></div>
}

The above change solved.

Thanks.

@joeelmahallawy
Copy link

I can confirm, I get the same error: "Expected static flag was missing. Please notify the React team." with the code below:

import React, { useMemo } from "react";
import { useTable, useSortBy, usePagination } from "react-table";

const JSONTable = ({ arr }: { arr?: object[] }) => {

  if (!arr?.length) return null;

  const data = useMemo(() => arr, [arr]);

  const keys = Object.keys(arr[0]);

  const columns = useMemo(
    () => keys.map((key) => ({ Header: key, accessor: key })),
    [arr]
  );

  const {
    getTableProps,
    getTableBodyProps,
    headerGroups,
    rows,
    prepareRow,
    page, // Instead of using 'rows', we'll use page,
    // which has only the rows for the active page

    // The rest of these things are super handy, too ;)
    canPreviousPage,
    canNextPage,
    pageOptions,
    pageCount,
    gotoPage,
    nextPage,
    previousPage,
    setPageSize,
    state: { pageIndex, pageSize },
  } = useTable(
    { columns, data, initialState: { pageIndex: 0 } },
    useSortBy,
    usePagination
  );

  return null;
}

However, I stop getting the error when I remove the following code below:

  const {
    getTableProps,
    getTableBodyProps,
    headerGroups,
    rows,
    prepareRow,
    page, // Instead of using 'rows', we'll use page,
    // which has only the rows for the active page

    // The rest of these things are super handy, too ;)
    canPreviousPage,
    canNextPage,
    pageOptions,
    pageCount,
    gotoPage,
    nextPage,
    previousPage,
    setPageSize,
    state: { pageIndex, pageSize },
  } = useTable(
    { columns, data, initialState: { pageIndex: 0 } },
    useSortBy,
    usePagination
  );

@gaearon
Copy link
Collaborator

gaearon commented May 19, 2022

The issue is the early return. Put the return after calls to Hooks. Please add the linter to your setup to detect these issues at compile time as originally intended.

@ahuigo
Copy link

ahuigo commented Mar 2, 2023

The issue is the early return. Put the return after calls to Hooks. Please add the linter to your setup to detect these issues at compile time as originally intended.

Bad case: https://codepen.io/ahuigo/pen/YzOVPQv

@3mper0r
Copy link

3mper0r commented Jun 19, 2023

Just ran at this error trying to validate forms within Modal with zod validation library and react hook form. Basically the error was coming when I was checking (conditional rendering) for the modal and I was doing before the useForm hook of react-hook-form.

The lesson here is: when you have any kind of hooks always do your conditional renderings at the bottom right before returning your jsx/tsx!

@vilelalabs
Copy link

The issue is exactly as what @gaearon said. In my case, the very first line of the component was checking a prop 'hidden' and returning a fragment if it is true. That was causing this error. Though it was not a best practice, V17 was OK with this.

SidebarItem.tsx Issue: image

The fix was to do the check after initiating the hook.

Fix: image

totally solved my problem.

I had in code

    if (!visible) return null;
    const proModal = useProModal();

and just moved up of component return:

    const proModal = useProModal();
    if (!visible) return null;

@Josema
Copy link

Josema commented Sep 27, 2023

Similar issue here. I am using react-native-web:

"react": "18.2.0",
"react-dom": "18.2.0",
"react-native": "0.71.8",
"react-native-web": "~0.18.10",

Is a simple hook that does this:

    const [cards, setCards] = useState([])

    useEffect(() => {
        ;(async () => {
            try {
                const cards = await Server.userCards({ user_id })
                setCards(cards)
            } catch (error) {
                //
            }
        })()
    }, [user_id, setCards])

If a comment the line setCards(cards) I don't get any error.

react-dom.development.js:86 Warning: Internal React error: Expected static flag was missing. Please notify the React team.
    at Deck (http://localhost:19006/static/js/bundle.js:27119:20)
    at div
    at http://localhost:19006/static/js/bundle.js:13035:25
    at http://localhost:19006/static/js/bundle.js:33953:45
    at div
    at http://localhost:19006/static/js/bundle.js:13035:25
    at http://localhost:19006/static/js/bundle.js:33953:45
    at div
    at http://localhost:19006/static/js/bundle.js:13035:25
    at http://localhost:19006/static/js/bundle.js:33953:45
    at div
    at http://localhost:19006/static/js/bundle.js:13035:25
    at http://localhost:19006/static/js/bundle.js:33953:45
    at div
    at http://localhost:19006/static/js/bundle.js:13035:25
    at http://localhost:19006/static/js/bundle.js:33953:45
    at div
    at http://localhost:19006/static/js/bundle.js:13035:25
    at div
    at http://localhost:19006/static/js/bundle.js:13035:25
    at http://localhost:19006/static/js/bundle.js:9361:24
    at ScrollView (http://localhost:19006/static/js/bundle.js:39905:37)
    at ScrollView
    at http://localhost:19006/static/js/bundle.js:33953:45
    at div
    at http://localhost:19006/static/js/bundle.js:13035:25
    at http://localhost:19006/static/js/bundle.js:33953:45
    at div
    at http://localhost:19006/static/js/bundle.js:13035:25
    at http://localhost:19006/static/js/bundle.js:33953:45
    at div
    at http://localhost:19006/static/js/bundle.js:13035:25
    at http://localhost:19006/static/js/bundle.js:7859:24
    at http://localhost:19006/static/js/bundle.js:33953:45
    at div
    at http://localhost:19006/static/js/bundle.js:13035:25
    at http://localhost:19006/static/js/bundle.js:33953:45
    at Lobby (http://localhost:19006/static/js/bundle.js:26652:23)
    at Cards (http://localhost:19006/static/js/bundle.js:27938:79)
    at div
    at http://localhost:19006/static/js/bundle.js:13035:25
    at http://localhost:19006/static/js/bundle.js:33953:45
    at div
    at http://localhost:19006/static/js/bundle.js:13035:25
    at http://localhost:19006/static/js/bundle.js:33953:45
    at Views (http://localhost:19006/static/js/bundle.js:25587:79)
    at App (http://localhost:19006/static/js/bundle.js:25525:70)
    at withDevTools(App)

@adaboese
Copy link

Getting this when using @sentry/react.

import { captureRemixErrorBoundaryError, withSentry } from '@sentry/remix';

const Root = () => {};

const RootWithSentry = withSentry(Root);

export default Root;

@rickhanlonii
Copy link
Member

@adaboese I'm not able to reproduce that example in a new Remix project, can you provide a full repro? I want to rule out the known issue above that hooks are being called conditionally.

@adaboese
Copy link

@adaboese I'm not able to reproduce that example in a new Remix project, can you provide a full repro? I want to rule out the known issue above that hooks are being called conditionally.

That turned out to be a false-positive.

Although I am not clear why adding/removing withSentry caused the issue/made it go away, but I am pretty sure that the issue is actually with this package. edmundhung/conform#375 (comment)

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

No branches or pull requests