react
react copied to clipboard
Bug: useId generated the same ID on server-side for 2 different mounted components when Promise/Suspense is involved
React version: 18.3.1
(Also tested on React 19 and seems like it is fixed)
Steps To Reproduce
- Create 2 components: Parent and Child, where both components will throw Promise (eg. data fetching)
- Call
useIdon both Parent and Child, and observes they have the same ID generated
Sample code:
const Child = ({ parentId }: { parentId: string }) => {
const id = useId();
useAsync(2); // Just assume it is a hook that will throw Promise in first call
return (
<ul>
<li>Parent: {parentId}</li>
<li>Child: {id}</li>
</ul>
);
};
const Parent = () => {
const id = useId();
useAsync(1); // Just assume it is a hook that will throw Promise in first call
return <Child parentId={id} />;
};
Generated HTML:
<ul>
<li>Parent: <!-- -->:R0:</li>
<li>Child: <!-- -->:R0:</li>
</ul>
Link to code example: https://codesandbox.io/p/sandbox/react-server-duplicate-useid-nllf55
The current behavior
The ID generated on both mounted components are the same
<ul>
<li>Parent: <!-- -->:R0:</li>
<li>Child: <!-- -->:R0:</li>
</ul>
The expected behavior
The ID generated on both mounted components should be different
<ul>
<li>Parent: <!-- -->:R0:</li>
<li>Child: <!-- -->:R1:</li>
</ul>