You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: src/content/reference/react/useId.md
+52-51Lines changed: 52 additions & 51 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -4,7 +4,7 @@ title: useId
4
4
5
5
<Intro>
6
6
7
-
`useId`is a React Hook for generating unique IDs that can be passed to accessibility attributes.
7
+
`useId`là một React Hook dùng để sinh ra các ID duy nhất có thể được dùng để truyền vào các thuộc tính accessibility.
8
8
9
9
```js
10
10
constid=useId()
@@ -20,7 +20,7 @@ const id = useId()
20
20
21
21
### `useId()` {/*useid*/}
22
22
23
-
Call`useId`at the top level of your component to generate a unique ID:
23
+
Gọi`useId`ở top level của component để sinh ra một ID duy nhất:
24
24
25
25
```js
26
26
import { useId } from'react';
@@ -30,37 +30,37 @@ function PasswordField() {
30
30
// ...
31
31
```
32
32
33
-
[See more examples below.](#usage)
33
+
[Xem nhiều ví dụ hơn ở bên dưới.](#usage)
34
34
35
-
#### Parameters {/*parameters*/}
35
+
#### Tham số {/*parameters*/}
36
36
37
-
`useId`does not take any parameters.
37
+
`useId`không nhận tham số.
38
38
39
-
#### Returns {/*returns*/}
39
+
#### Trả về {/*returns*/}
40
40
41
-
`useId`returns a unique ID string associated with this particular `useId`call in this particular component.
41
+
`useId`trả về một ID dạng chuỗi duy nhất với lần gọi `useId`trong component hiện tại.
42
42
43
-
#### Caveats {/*caveats*/}
43
+
#### Lưu ý {/*caveats*/}
44
44
45
-
* `useId`is a Hook, so you can only call it **at the top level of your component** or your own Hooks. You can't call it inside loops or conditions. If you need that, extract a new component and move the state into it.
45
+
* `useId`là một Hook, vì vậy bạn chỉ có thể gọi nó **ở top level của component** hoặc các Hook tuỳ chỉnh của bạn. Bạn không thể gọi nó bên trong vòng lặp hoặc trong câu lệnh điều kiện. Nếu bạn cần làm vậy, hãy tách nó thành một component mới và di chuyển state vào đó.
46
46
47
-
* `useId` **should not be used to generate keys** in a list. [Keys should be generated from your data.](/learn/rendering-lists#where-to-get-your-key)
47
+
* `useId` **không nên được sử dụng để sinh key** cho danh sách. [Key nên được tạo từ dữ liệu của bạn.](/learn/rendering-lists#where-to-get-your-key)
48
48
49
-
* `useId`currently cannot be used in [async Server Components](/reference/rsc/server-components#async-components-with-server-components).
49
+
* `useId`hiện tại không thể sử dụng trong [async Server Component](/reference/rsc/server-components#async-components-with-server-components).
50
50
51
51
---
52
52
53
-
## Usage {/*usage*/}
53
+
## Sử dụng {/*usage*/}
54
54
55
55
<Pitfall>
56
56
57
-
**Do not call `useId`to generate keys in a list.** [Keys should be generated from your data.](/learn/rendering-lists#where-to-get-your-key)
57
+
**Không gọi `useId`để sinh key trong một danh sách.** [Key nên được tạo từ dữ liệu của bạn.](/learn/rendering-lists#where-to-get-your-key)
58
58
59
59
</Pitfall>
60
60
61
-
### Generating unique IDs for accessibility attributes {/*generating-unique-ids-for-accessibility-attributes*/}
61
+
### Sinh ID duy nhất cho các thuộc tính accessibility {/*generating-unique-ids-for-accessibility-attributes*/}
62
62
63
-
Call`useId`at the top level of your component to generate a unique ID:
63
+
Gọi`useId`tại top level của component để sinh ra một ID duy nhất:
64
64
65
65
```js [[1, 4, "passwordHintId"]]
66
66
import { useId } from'react';
@@ -70,7 +70,7 @@ function PasswordField() {
70
70
// ...
71
71
```
72
72
73
-
You can then pass the <CodeStep step={1}>generated ID</CodeStep> to different attributes:
73
+
Sau đó bạn có thể truyền <CodeStep step={1}>ID đã sinh ra</CodeStep> vào các thuộc tính khác:
@@ -79,26 +79,26 @@ You can then pass the <CodeStep step={1}>generated ID</CodeStep> to different at
79
79
</>
80
80
```
81
81
82
-
**Let's walk through an example to see when this is useful.**
82
+
**Hãy xem một ví dụ để thấy khi nào nó hữu ích.**
83
83
84
-
[HTML accessibility attributes](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA) like [`aria-describedby`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-describedby) let you specify that two tags are related to each other. For example, you can specify that an element (like an input) is described by another element (like a paragraph).
84
+
[HTML accessibility attributes](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA) như [`aria-describedby`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-describedby) cho bạn chỉ định rằng hai thẻ có liên quan với nhau. Ví dụ, bạn có thể chỉ định rằng một phần tử (như input) được mô tả bởi một phần tử khác (như đoạn văn).
85
85
86
-
In regular HTML, you would write it like this:
86
+
Trong HTML thuần, bạn sẽ viết như sau:
87
87
88
88
```html {5,8}
89
89
<label>
90
-
Password:
90
+
Mật khẩu:
91
91
<input
92
92
type="password"
93
93
aria-describedby="password-hint"
94
94
/>
95
95
</label>
96
96
<p id="password-hint">
97
-
The password should contain at least18characters
97
+
Mật khẩu nên chứa ít nhất18ký tự
98
98
</p>
99
99
```
100
100
101
-
However, hardcoding IDs like this is not a good practice in React. A component may be rendered more than once on the page--but IDs have to be unique! Instead of hardcoding an ID, generate a unique ID with`useId`:
101
+
Tuy nhiên, việc hardcode ID như thế không phải là một practice tốt trong React. một component có thể được render nhiều lần trên trang--nhưng ID thì phải là duy nhất! Thay vì hardcode một ID, hãy sinh ra một ID duy nhất với`useId`:
102
102
103
103
```js {4,11,14}
104
104
import { useId } from'react';
@@ -108,21 +108,21 @@ function PasswordField() {
108
108
return (
109
109
<>
110
110
<label>
111
-
Password:
111
+
Mật khẩu:
112
112
<input
113
113
type="password"
114
114
aria-describedby={passwordHintId}
115
115
/>
116
116
</label>
117
117
<p id={passwordHintId}>
118
-
The password should contain at least18characters
118
+
Mật khẩu nên chứa ít nhất18ký tự
119
119
</p>
120
120
</>
121
121
);
122
122
}
123
123
```
124
124
125
-
Now, even if `PasswordField` appears multiple times on the screen, the generated IDs won't clash.
125
+
Và giờ, ngay cả khi bạn render nhiều instance của `PasswordField`, các ID được sinh ra sẽ không bị trùng lặp:
126
126
127
127
<Sandpack>
128
128
@@ -134,14 +134,14 @@ function PasswordField() {
134
134
return (
135
135
<>
136
136
<label>
137
-
Password:
137
+
Mật khẩu:
138
138
<input
139
139
type="password"
140
140
aria-describedby={passwordHintId}
141
141
/>
142
142
</label>
143
143
<p id={passwordHintId}>
144
-
The password should contain at least18characters
144
+
Mật khẩu nên chứa ít nhất18ký tự
145
145
</p>
146
146
</>
147
147
);
@@ -150,9 +150,9 @@ function PasswordField() {
150
150
exportdefaultfunctionApp() {
151
151
return (
152
152
<>
153
-
<h2>Choose password</h2>
153
+
<h2>Tạo mật khẩu</h2>
154
154
<PasswordField />
155
-
<h2>Confirm password</h2>
155
+
<h2>Xác nhận mật khẩu</h2>
156
156
<PasswordField />
157
157
</>
158
158
);
@@ -165,33 +165,33 @@ input { margin: 5px; }
165
165
166
166
</Sandpack>
167
167
168
-
[Watch this video](https://www.youtube.com/watch?v=0dNzNcuEuOo) to see the difference in the user experience with assistive technologies.
168
+
[Xem video này](https://www.youtube.com/watch?v=0dNzNcuEuOo) để thấy sự khác biệt trong trải nghiệm người dùng với các công nghệ hỗ trợ.
169
169
170
170
<Pitfall>
171
171
172
-
With [server rendering](/reference/react-dom/server), **`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.
172
+
Với [server rendering](/reference/react-dom/server), **`useId`yêu cầu component tree phải giống hệt nhau trên server và client**. Nếu cây bạn render trên server và client không khớp hoàn toàn, các ID được sinh ra sẽ không khớp.
173
173
174
174
</Pitfall>
175
175
176
176
<DeepDive>
177
177
178
-
#### Why is useId better than an incrementing counter? {/*why-is-useid-better-than-an-incrementing-counter*/}
178
+
#### Tại sao useId tốt hơn một counter tăng dần {/*why-is-useid-better-than-an-incrementing-counter*/}
179
179
180
-
You might be wondering why `useId`is better than incrementing a global variable like`nextId++`.
180
+
Bạn có thể sẽ thắc mắc tại sao `useId`lại tốt hơn là tăng một biến toàn cục như`nextId++`.
181
181
182
-
The primary benefit of`useId`is that React ensures that it works with [server rendering.](/reference/react-dom/server) During server rendering, your components generate HTML output. Later, on the client, [hydration](/reference/react-dom/client/hydrateRoot) attaches your event handlers to the generated HTML. For hydration to work, the client output must match the server HTML.
182
+
Lợi ích chính của`useId`là React đảm bảo rằng nó hoạt động với [server rendering.](/reference/react-dom/server) Trong server rendering, các component của bạn sinh ra output HTML. Sau đó, trên client, [hydration](/reference/react-dom/client/hydrateRoot) gắn các event handler của bạn vào HTML đã sinh ra. Để hydration hoạt động, output trên client phải khớp với HTML trên server.
183
183
184
-
This is very difficult to guarantee with an incrementing counter because the order in which the Client Components are hydrated may not match the order in which the server HTML was emitted. By calling `useId`, you ensure that hydration will work, and the output will match between the server and the client.
184
+
Điều này quá khó để đảm bảo với một biến đếm tăng dần vì thứ tự mà các Client Component được hydrated có thể không khớp với thứ tự mà HTML trên server được sinh ra. Bằng cách gọi `useId`, bạn đảm bảo rằng hydration sẽ hoạt động, và output sẽ khớp giữa server và client.
185
185
186
-
Inside React, `useId`is generated from the "parent path" of the calling component. This is why, if the client and the server tree are the same, the "parent path" will match up regardless of rendering order.
186
+
Trong React, `useId`được sinh ra từ "parent path" của component gọi nó. Đây là lý do tại sao, nếu cây trên client và server giống nhau, "parent path" sẽ khớp với nhau bất kể thứ tự render.
187
187
188
188
</DeepDive>
189
189
190
190
---
191
191
192
-
### Generating IDs for several related elements {/*generating-ids-for-several-related-elements*/}
192
+
### Sinh ID cho nhiều phần tử liên quan {/*generating-ids-for-several-related-elements*/}
193
193
194
-
If you need to give IDs to multiple related elements, you can call `useId`to generate a shared prefix for them:
194
+
Nếu bạn cần gán ID cho nhiều phần tử liên quan, bạn có thể gọi `useId`để sinh ra một tiền tố (prefix) dùng chung cho chúng:
195
195
196
196
<Sandpack>
197
197
@@ -202,29 +202,30 @@ export default function Form() {
This lets you avoid calling `useId`for every single element that needs a unique ID.
222
+
Điều này giúp bạn tránh phải gọi `useId`cho từng phần tử cần ID duy nhất.
222
223
223
224
---
224
225
225
-
### Specifying a shared prefix for all generated IDs {/*specifying-a-shared-prefix-for-all-generated-ids*/}
226
+
### Đặt tiền tố dùng chung cho tất cả ID được sinh ra {/*specifying-a-shared-prefix-for-all-generated-ids*/}
226
227
227
-
If you render multiple independent React applications on a single page, pass `identifierPrefix`as an option to your [`createRoot`](/reference/react-dom/client/createRoot#parameters) or [`hydrateRoot`](/reference/react-dom/client/hydrateRoot) calls. This ensures that the IDs generated by the two different apps never clash because every identifier generated with `useId`will start with the distinct prefix you've specified.
228
+
Nếu bạn render nhiều ứng dụng React độc lập trên một trang, hãy truyền `identifierPrefix`như một tuỳ chọn vào các lệnh gọi [`createRoot`](/reference/react-dom/client/createRoot#parameters) hoặc [`hydrateRoot`](/reference/react-dom/client/hydrateRoot). Điều này đảm bảo rằng các ID được sinh ra bởi hai ứng dụng khác nhau sẽ không bao giờ bị trùng lặp vì mỗi ID được sinh ra với `useId`sẽ bắt đầu với tiền tố riêng biệt mà bạn đã chỉ định.
228
229
229
230
<Sandpack>
230
231
@@ -248,14 +249,14 @@ function PasswordField() {
248
249
return (
249
250
<>
250
251
<label>
251
-
Password:
252
+
Mật khẩu:
252
253
<input
253
254
type="password"
254
255
aria-describedby={passwordHintId}
255
256
/>
256
257
</label>
257
258
<p id={passwordHintId}>
258
-
The password should contain at least18characters
259
+
Mật khẩu nên chứa ít nhất18ký tự
259
260
</p>
260
261
</>
261
262
);
@@ -264,7 +265,7 @@ function PasswordField() {
264
265
exportdefaultfunctionApp() {
265
266
return (
266
267
<>
267
-
<h2>Choose password</h2>
268
+
<h2>Tạo mật khẩu</h2>
268
269
<PasswordField />
269
270
</>
270
271
);
@@ -307,9 +308,9 @@ input { margin: 5px; }
307
308
308
309
---
309
310
310
-
### Using the same ID prefix on the client and the server {/*using-the-same-id-prefix-on-the-client-and-the-server*/}
311
+
### Sử dụng cùng một tiền tố ID trên client và server {/*using-the-same-id-prefix-on-the-client-and-the-server*/}
311
312
312
-
If you [render multiple independent React apps on the same page](#specifying-a-shared-prefix-for-all-generated-ids), and some of these apps are server-rendered, make sure that the`identifierPrefix`you pass to the [`hydrateRoot`](/reference/react-dom/client/hydrateRoot) call on the client side is the same as the `identifierPrefix`you pass to the [server APIs](/reference/react-dom/server) such as [`renderToPipeableStream`.](/reference/react-dom/server/renderToPipeableStream)
313
+
Nếu bạn [render nhiều ứng dụng React độc lập trên cùng một trang](#specifying-a-shared-prefix-for-all-generated-ids), và một số trong các ứng dụng này được server-rendered, hãy đảm bảo rằng`identifierPrefix`bạn truyền vào lệnh gọi [`hydrateRoot`](/reference/react-dom/client/hydrateRoot) ở phía client giống với `identifierPrefix`bạn truyền vào các [API server](/reference/react-dom/server) như [`renderToPipeableStream`.](/reference/react-dom/server/renderToPipeableStream)
313
314
314
315
```js
315
316
// Server
@@ -333,4 +334,4 @@ const root = hydrateRoot(
333
334
);
334
335
```
335
336
336
-
You do not need to pass `identifierPrefix`if you only have one React app on the page.
337
+
Bạn không cần truyền `identifierPrefix`nếu bạn chỉ có một ứng dụng React trên trang.
0 commit comments