-
-
Notifications
You must be signed in to change notification settings - Fork 8.3k
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
feat(runtime-core): useId() #11404
feat(runtime-core): useId() #11404
Conversation
Size ReportBundles
Usages
|
can this be used for |
After working with Was this a deliberate design decision? If so, could you share the reasoning behind it? |
Code ExampleHere's a simple example to illustrate the issue:
|
Thanks for implementing the |
@dadaguai-git This simple change can generate unique IDs in asynchronous contexts. This api design maybe is intended to be consistent with React's useId. /** useId */
export function useIdCreator() {
const i = getCurrentInstance()
if (i) {
// return (i.appContext.config.idPrefix || 'v') + ':' + i.ids[0] + i.ids[1]++
return () => (i.appContext.config.idPrefix || 'v') + ':' + i.ids[0] + i.ids[1]++
} else if (__DEV__) {
warn(
`useId() is called when there is no active component ` +
`instance to be associated with.`,
)
}
} |
export function useId() { | ||
const i = getCurrentInstance() | ||
if (i) { | ||
return (i.appContext.config.idPrefix || 'v') + i.ids[0] + ':' + i.ids[1]++ | ||
} else if (__DEV__) { | ||
warn( | ||
`useId() is called when there is no active component ` + | ||
`instance to be associated with.`, | ||
) | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@yyx990803 is there any good reason to not throw an error in case i == false
?
The code as it is right now results in return type of string | undefined
.
Sure, a user might call useId
outside a component, but I feel like this should just produce an error.
I am having the same problem as @dr46ul describes here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
None of the APIs that require an active currentInstance throws. This avoids breaking the entire user experience in unexpected cases and leaves the option to throw to the developer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd argue that not throwing in a situation where an active currentInstance is required constitutes "silent failure". But then again console warnings are issued and I might have spent too much time in python-land recently to appreciate avoiding a throw. 😂
Thanks for explaining! 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason then it cannot return an empty string, (or some type of string) rather than undefined
?
The string | undefined
return type causes downstream apps (including Nuxt) to have to do something like useId()!
or YOLO cast const myId = useId() as string
to avoid having to account for undefined
even when the dev knows they are calling it properly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess yolo-casting ist he way to go if you know you are calling it properly? (i.e. inside a component).
I now actually sort of appreciate this Situation since I was calling useId
inside a composable and handling this situation explicitly (with a throw) prevents missunderstandings like trying to use it in a store. (But there are other composables that could be used in a store).
How can I use this feature in lists? |
You can't |
Similar to React's useId, this composable returns a unique ID that can be used for form elements and accessibility attributes.
The generated IDs look like
v:1-2-3
and are unique across each app instance and are stable across server rendering and client rendering. This is ensured by dividing an app into async boundaries (async components, async setup, serverPrefetch). The order of appearance of direct child async boundaries are always consistent assuming the same data is used between server and client, but their order of resolution may be different. Even if two async boundaries resolve in different orders between server and client,useId()
calls inside the two boundaries should not affect each other.Example Usage
App Scoped
Note IDs generated are unique-per-app-instance. If you have multiple apps on the same page, you can configure an app-level prefix for each app via
app.config.idPrefix
: