0
# ID & Reference Management
1
2
Core utilities for generating accessible IDs and managing React refs across components. These utilities ensure proper accessibility attributes and ref handling in React Aria components.
3
4
## Capabilities
5
6
### useId Hook
7
8
Generates unique IDs for DOM elements with SSR safety and collision avoidance.
9
10
```typescript { .api }
11
/**
12
* Generates a unique ID for DOM elements, with SSR safety
13
* @param defaultId - Optional default ID to use
14
* @returns A unique string ID that's stable across renders
15
*/
16
function useId(defaultId?: string): string;
17
```
18
19
**Usage Examples:**
20
21
```typescript
22
import { useId } from "@react-aria/utils";
23
24
function MyComponent() {
25
const labelId = useId();
26
const inputId = useId("my-input"); // Uses provided ID if no conflicts
27
28
return (
29
<div>
30
<label id={labelId} htmlFor={inputId}>Name</label>
31
<input id={inputId} aria-labelledby={labelId} />
32
</div>
33
);
34
}
35
```
36
37
### mergeIds Function
38
39
Merges two IDs and triggers re-renders in hooked components when IDs change.
40
41
```typescript { .api }
42
/**
43
* Merges two IDs, prioritizing the second ID if different
44
* @param idA - First ID
45
* @param idB - Second ID
46
* @returns The merged ID (idB takes precedence if different from idA)
47
*/
48
function mergeIds(idA: string, idB: string): string;
49
```
50
51
**Usage Examples:**
52
53
```typescript
54
import { mergeIds, useId } from "@react-aria/utils";
55
56
function FormField({ id, ...props }) {
57
const defaultId = useId();
58
const finalId = mergeIds(defaultId, id);
59
60
return <input id={finalId} {...props} />;
61
}
62
```
63
64
### useSlotId Hook
65
66
Generates an ID and checks if it exists in DOM after render for conditional aria-labelledby attributes.
67
68
```typescript { .api }
69
/**
70
* Generates an ID and checks if it exists in DOM after render
71
* @param depArray - Optional dependency array for recalculating DOM presence
72
* @returns ID string that's stable across renders
73
*/
74
function useSlotId(depArray?: ReadonlyArray<any>): string;
75
```
76
77
**Usage Examples:**
78
79
```typescript
80
import { useSlotId } from "@react-aria/utils";
81
82
function Dialog({ children }) {
83
const titleId = useSlotId([children]);
84
85
return (
86
<div
87
role="dialog"
88
aria-labelledby={titleId} // Only set if title element exists
89
>
90
{children}
91
</div>
92
);
93
}
94
95
function DialogTitle({ children, ...props }) {
96
const id = useSlotId();
97
return <h2 id={id} {...props}>{children}</h2>;
98
}
99
```
100
101
### mergeRefs Function
102
103
Combines multiple refs (object or callback) into a single ref function.
104
105
```typescript { .api }
106
/**
107
* Combines multiple refs into a single ref function
108
* @param refs - Array of refs (object refs, callback refs, or null/undefined)
109
* @returns Combined ref function that updates all provided refs
110
*/
111
function mergeRefs<T>(...refs: (Ref<T> | null | undefined)[]): Ref<T>;
112
```
113
114
**Usage Examples:**
115
116
```typescript
117
import { mergeRefs } from "@react-aria/utils";
118
import { useRef, forwardRef } from "react";
119
120
const MyInput = forwardRef<HTMLInputElement, InputProps>((props, ref) => {
121
const localRef = useRef<HTMLInputElement>(null);
122
const combinedRef = mergeRefs(ref, localRef);
123
124
return <input ref={combinedRef} {...props} />;
125
});
126
```
127
128
### useObjectRef Hook
129
130
Converts callback refs or forwarded refs to object refs for use with React Aria hooks.
131
132
```typescript { .api }
133
/**
134
* Converts callback refs or forwarded refs to object refs
135
* @param ref - Original ref (callback, object, or null)
136
* @returns Object ref that updates the original ref
137
*/
138
function useObjectRef<T>(ref?: ForwardedRef<T>): MutableRefObject<T | null>;
139
```
140
141
**Usage Examples:**
142
143
```typescript
144
import { useObjectRef } from "@react-aria/utils";
145
import { useButton } from "@react-aria/button";
146
import { forwardRef } from "react";
147
148
const Button = forwardRef<HTMLButtonElement, ButtonProps>((props, ref) => {
149
const objectRef = useObjectRef(ref);
150
const { buttonProps } = useButton(props, objectRef);
151
152
return <button ref={objectRef} {...buttonProps} />;
153
});
154
```
155
156
### useSyncRef Hook
157
158
Synchronizes a ref with a context value for keeping refs in sync across components.
159
160
```typescript { .api }
161
/**
162
* Synchronizes a ref with a context value
163
* @param context - Context to sync with
164
* @param ref - Ref to synchronize
165
*/
166
function useSyncRef<T>(context: Context<T>, ref: MutableRefObject<T>): void;
167
```
168
169
**Usage Examples:**
170
171
```typescript
172
import { useSyncRef } from "@react-aria/utils";
173
import { createContext, useContext, useRef } from "react";
174
175
const MyContext = createContext<HTMLElement | null>(null);
176
177
function ContextProvider({ children }) {
178
const ref = useRef<HTMLElement>(null);
179
useSyncRef(MyContext, ref);
180
181
return (
182
<MyContext.Provider value={ref.current}>
183
<div ref={ref}>
184
{children}
185
</div>
186
</MyContext.Provider>
187
);
188
}
189
```
190
191
## Types
192
193
```typescript { .api }
194
type Ref<T> = MutableRefObject<T> | ((instance: T | null) => void) | null;
195
type ForwardedRef<T> = ((instance: T | null) => void) | MutableRefObject<T | null> | null;
196
```