-
Notifications
You must be signed in to change notification settings - Fork 49.3k
Description
"Internal React error: Expected static flag was missing. Please notify the React team."
This error message appeared after I created the component in the following code example. I pinpointed the issue down to the recursive nature of the component, which seems to confuse react in a way that it does not handle the early return before the calls to react hooks (which I placed there by accident) correctly.
"use client";
import { useEffect, useState } from "react";
/* dummy type */
type ProductGroup = { id: string, name: string };
type SubGroupProps = {
depth: number,
label: string,
root: ProductGroup[],
action: (id: string) => Promise<ProductGroup[]>,
}
/* create recursive subgroups to select from */
function SubGroupFilter({ depth, label, root, action }: Readonly<SubGroupProps>) {
/* ------- BUG FROM HERE ------- */
/* early return */
if (!root.length)
return;
/* does not get catched!! */
const [index, setIndex] = useState<number>(0);
const [items, setItems] = useState<ProductGroup[]>([]);
useEffect(() => {
action(root[index].id).then(setItems);
}, [root, action, index, setItems]);
/* ---------- TO HERE ---------- */
return (
<>
<fieldset>
<legend>{label}</legend>
<select name="product-group" onChange={event => setIndex(event.currentTarget.selectedIndex)}>
{root.map(item => (
<option key={item.id} value={item.id}>
{item.name}
</option>
))}
</select>
</fieldset>
<SubGroupFilter depth={depth + 1} label={`Subgroup - ${root[index].name}`} root={items} action={action} />
</>
);
}
type SearchFormProps = {
root: ProductGroup[],
action: (id: string) => Promise<ProductGroup[]>,
}
export function SearchForm({ root, action }: Readonly<SearchFormProps>) {
return (
< >
<span >Search Form</span>
<form>
<SubGroupFilter depth={0} label="Product groups" root={root} action={action} />
<button className="button">search</button>
</form>
</>
);
}
<SearchForm root={[{
id: "foo1",
name: "Foo1"
}, {
id: "foo2",
name: "Foo2"
}, {
id: "foo3",
name: "Foo3"
}, {
id: "foo4",
name: "Foo4"
}, {
id: "foo5",
name: "Foo5"
}]} action={async (id: string) => {
"use server";
if (id === "foo1" || id === "foo1-foo2" || id === "foo1-foo2-foo3")
return [{
id: `${id}-foo1`,
name: "Foo1"
}, {
id: `${id}-foo2`,
name: "Foo2"
}, {
id: `${id}-foo3`,
name: "Foo3"
}, {
id: `${id}-foo4`,
name: "Foo4"
}, {
id: `${id}-foo5`,
name: "Foo5"
}];
return [];
}}>
</SearchForm>
React version: 19.1.0
Steps To Reproduce
- create a new component with recursive subcomponents (like here with the filter subgroups)
- make those recursive subcomponents call react hooks after an early return
In the example provided above the error message pops up every time a new subgroup appears, after selecting a parent group.
The issue does not appear when properly calling react hooks, i.e. move the return after the block of hook calls.
The current and expected behavior
There is seemingly no change in behavior, nor any other issues except for the error message.
Hope this bug report somehow helps fixing the issue and make React a little better than it already is.