Comments (8)
I also ran into this issue! One workaround I found that respects React’s rules and StrictMode rules is to move the generation of such IDs to outside of the component—if that’s an option for you.
For example:
function Outer() {
const id = useId()
return <Inner id={id} />
}
function Inner() {
const id = props.id; // Read stable ID from props instead
console.log("RENDER", id);
useMemo(() => {
console.log("MEMO");
}, []);
useEffect(() => {
console.log("MOUNT");
return () => {
console.log("UN-MOUNT");
};
}, []);
}
This way, each component behaves correctly in its own “strict mode” context.
I hated this solution as it definitely feels like a workaround / fighting the system, though. But maybe this sparks a new branch of thoughts. I’m still open to finding a better solution for this too.
from react.
I'm not React maintainer, but I don't think this has an easy fix because of what StrictMode does. Also this usually should not cause trouble.
@JSerZANP I am aware of what StrictMode
does. The problem is the order in which everything is happening. Each instance of a component should have its own unique and persistent ID. So, it makes sense that the ID changes after the component un-mounts and mounts again, but not across re-renders of the same instance (before un-mount happens).
Now, I am also aware that having useId
working as described above (which is the only way it should work in my opinion) opens the possibility to bypass other hooks strict controls (like useMemo
that will be called twice and useRef
that will reset its value after the second render). For example, by keeping an external storage using the instance ID.
But, if this is in fact on purpose, then I really think it is an exaggeration. It makes useId
unsound, broken. If people want to consciously do strange things and maybe navigate the grey areas of StrictMode
rules, so be it. But we cannot make useId
"useless".
As it is right now, it could only be reliably used for input/label HTML IDs... so, at least, change the hook name right? So people will not get confused thinking that ID actually remains constant through the entire life of the instance.
It also makes it very easy to create memory leaks.
Again, in some way it is genius. The ID is coherent inside the useEffect
(mount/unmount). Makes sense if it is on purpose to avoid non-pure logic in the component body, but it should be at least documented.
I've been working with React for years and I cannot wrap my head around this.
from react.
I see the same issue and I think it has something to do with the useEffect. I'm not sure but for me useEffect always makes everything run 2 times for me instead of the 1 time that it's supposed to. Like not only is it rendering a different ID but it is also mounting twice. Is it supposed to Mount twice? I'm a beginner and just looking into these things. please tell me what you think. thank you.
from react.
hmm I'm looking more into this and yes the useId Hook has a problem it says : "With server rendering, useId requires an identical component tree on the server and the client. If the trees you render on the server and the client don’t match exactly, the generated IDs won’t match"
maybe this is the problem although I still don't know what the identical component tree on a server and a client is. But what you are experiencing is "normal"? I'm not sure.
from react.
Not sure if related, but https://codesandbox.io/p/sandbox/empty-butterfly-y36f8d?file=%2Fapp%2Flayout.tsx%3A1%2C1 in Next.js App Dir pages, a similar issue is happening.
Edit
Nope, looks like vercel/next.js#53110 is a Next.js issue.
from react.
I guess this is expected behavior.
-
under
<StrictMode/>
, component is rendered twice https://github.com/facebook/react/blob/main/packages/react-reconciler/src/ReactFiberHooks.js#L597-L610 -
and for
useId()
, it falls back to a global counter if it is no in hydration.https://github.com/facebook/react/blob/main/packages/react-reconciler/src/ReactFiberHooks.js#L2613-L2632
In your demo, you are NOT doing hydration and also under <StrictMode/>
so you get different ids.
This is not about useId()
, if you switch to const [id] = useState(() => performance.now())
, you still get the unstable ids.
I'm not React maintainer, but I don't think this has an easy fix because of what StrictMode does. Also this usually should not cause trouble.
from react.
This issue has been automatically marked as stale. If this issue is still affecting you, please leave any comment (for example, "bump"), and we'll keep it open. We are sorry that we haven't been able to prioritize it yet. If you have any new additional information, please include it with your comment!
from react.
bump
from react.
Related Issues (20)
- Bug: Input of type number is incrementing/decrementing on mouse scroll
- Bug: render time differ depending on load
- How can I force update a class component in SyncLane? Can we permanently expose runWithPriority API? HOT 13
- Bug: StrictMode is not preventing side effects HOT 2
- [DevTools Bug]: After updating to version 5.1 the Dev tools fails to inspect elements
- Bug: HOT 1
- [React 19] Async transitions race condition handling
- Bug: React 18.3 warning says to import `act` from `react`, only `unstable_act` exists HOT 3
- Bug: "React Developer Tools" Chrome Extension unable to profile page rendering
- Bug: Source not displayed in DevTools HOT 2
- Bug:
- [React 19] useTransition()'s pending state does not go back to false (revision 94eed63c49-20240425) HOT 3
- Changelog for 18.3 is missing HOT 1
- [React 19] Removal of `ReactDOM.findDOMNode` HOT 2
- [React 19] react-test-renderer deprecation HOT 2
- E-Commerce HOT 1
- [React 19] HOT 1
- [React 19] Eslint React JSDoc support HOT 1
- [React 19] Support scoped custom element registries (i.e, react with Custom Elements being rendered in a shadow root)
- Bug [React-DOM]: Missing "bun" export field in package.json HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from react.