GithubHelp home page GithubHelp logo

Comments (8)

nvie avatar nvie commented on May 3, 2024 3

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.

ernestostifano avatar ernestostifano commented on May 3, 2024 1

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.

TamashiiD avatar TamashiiD commented on May 3, 2024

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.

TamashiiD avatar TamashiiD commented on May 3, 2024

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.

icyJoseph avatar icyJoseph commented on May 3, 2024

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.

JSerZANP avatar JSerZANP commented on May 3, 2024

I guess this is expected behavior.

  1. under <StrictMode/>, component is rendered twice https://github.com/facebook/react/blob/main/packages/react-reconciler/src/ReactFiberHooks.js#L597-L610

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

github-actions avatar github-actions commented on May 3, 2024

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.

ernestostifano avatar ernestostifano commented on May 3, 2024

bump

from react.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.