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
Hãy để ý cách component `App` không cần biết `Toolbar` sẽ làm gì với `onPlayMovie` hoặc `onUploadImage`. Đó là chi tiết thực thi của riêng `Toolbar`. Ở đây, `Toolbar` truyền chúng bằng các prop hàm xử lý `onClick` xuống các `Button` của `Toolbar`, nhưng `Toolbar` cũng có thể kích hoạt chúng sau trên phím tắt của bàn phím. Đặt tên prop theo các tương tác riêng của ứng dụng như `onPlayMovie` cho bạn sự linh hoạt trong việc thay đổi cách sử dụng chúng sau này.
316
316
317
-
## Event propagation {/*event-propagation*/}
317
+
## Sự lan truyền sự kiện {/*event-propagation*/}
318
318
319
-
Event handlers will also catch events from any children your component might have. We say that an event "bubbles" or "propagates" up the tree: it starts with where the event happened, and then goes up the tree.
319
+
Các hàm xử lý sự kiện cũng sẽ bắt các sự kiện từ bất cứ component con nào mà component của bạn có thể có. Ta nói sự kiện "nổi bọt" hay "lan truyền" lên cây component: bắt đầu từ nơi sự kiện xảy ra, và sau đó lan lên trên cây.
320
320
321
-
This `<div>` contains two buttons. Both the `<div>` *and* each button have their own `onClick` handlers. Which handlers do you think will fire when you click a button?
321
+
`<div>` này chứa hai nút. Cả `<div>` *và* mỗi nút đều có hàm xử lý `onClick` riêng. Bạn nghĩ hàm xử lý nào sẽ được kích hoạt khi bạn nhấn vào một nút?
322
322
323
323
<Sandpack>
324
324
325
325
```js
326
326
export default function Toolbar() {
327
327
return (
328
328
<div className="Toolbar" onClick={() => {
329
-
alert('You clicked on the toolbar!');
329
+
alert('Bạn đã nhấn vào thanh công cụ!');
330
330
}}>
331
-
<button onClick={() => alert('Playing!')}>
332
-
Play Movie
331
+
<button onClick={() => alert('Đang phát!')}>
332
+
Phát phim
333
333
</button>
334
-
<button onClick={() => alert('Uploading!')}>
335
-
Upload Image
334
+
<button onClick={() => alert('Đang tải lên!')}>
335
+
Tải ảnh lên
336
336
</button>
337
337
</div>
338
338
);
@@ -349,19 +349,19 @@ button { margin: 5px; }
349
349
350
350
</Sandpack>
351
351
352
-
If you click on either button, its `onClick` will run first, followed by the parent `<div>`'s `onClick`. So two messages will appear. If you click the toolbar itself, only the parent `<div>`'s `onClick` will run.
352
+
Nếu bạn nhấn vào một trong hai nút, `onClick` của nút đó sẽ chạy trước, tiếp đến là `onClick` của `<div>` cha. Nên hai lời nhắn sẽ xuất hiện. Nếu bạn nhấn vào thanh công cụ, sẽ chỉ có `onClick` của `<div>` cha chạy.
353
353
354
354
<Pitfall>
355
355
356
-
All events propagate in React except `onScroll`, which only works on the JSX tag you attach it to.
356
+
Tất cả sự kiện đều lan truyền trong React ngoại trừ `onScroll`, nó chỉ hoạt động trên thẻ JSX mà bạn gắn nó.
Event handlers receive an **event object** as their only argument. By convention, it's usually called `e`, which stands for "event". You can use this object to read information about the event.
362
+
Các hàm xử lý sự kiện nhận một đối tượng sự kiện làm tham số duy nhất. Theo quy chuẩn, tham số này thường được gọi là `e`, viết tắt cho `event` (sự kiện). Bạn có thể sử dụng dối tượng này để đọc thông tin về sự kiện.
363
363
364
-
That event object also lets you stop the propagation. If you want to prevent an event from reaching parent components, you need to call `e.stopPropagation()` like this `Button` component does:
364
+
Đối tượng sự kiện đó cũng cho bạn dừng sự lan truyền. Nếu bạn muốn ngăn một sự kiện truyền tới các component cha, bạn cần gọi `e.stopPropagation()` như component `Button` dưới đây:
365
365
366
366
<Sandpack>
367
367
@@ -380,13 +380,13 @@ function Button({ onClick, children }) {
380
380
export default function Toolbar() {
381
381
return (
382
382
<div className="Toolbar" onClick={() => {
383
-
alert('You clicked on the toolbar!');
383
+
alert('Bạn đã nhấn vào thanh công cụ!');
384
384
}}>
385
-
<Button onClick={() => alert('Playing!')}>
386
-
Play Movie
385
+
<Button onClick={() => alert('Đang phát!')}>
386
+
Phát phim
387
387
</Button>
388
-
<Button onClick={() => alert('Uploading!')}>
389
-
Upload Image
388
+
<Button onClick={() => alert('Đang tải lên!')}>
389
+
Tải ảnh lên
390
390
</Button>
391
391
</div>
392
392
);
@@ -403,43 +403,43 @@ button { margin: 5px; }
403
403
404
404
</Sandpack>
405
405
406
-
When you click on a button:
406
+
Khi bạn nhấn vào một nút:
407
407
408
-
1. React calls the `onClick` handler passed to `<button>`.
409
-
2. That handler, defined in `Button`, does the following:
410
-
* Calls `e.stopPropagation()`, preventing the event from bubbling further.
411
-
* Calls the `onClick` function, which is a prop passed from the `Toolbar` component.
412
-
3. That function, defined in the `Toolbar` component, displays the button's own alert.
413
-
4. Since the propagation was stopped, the parent `<div>`'s `onClick` handler does *not* run.
408
+
1. React gọi hàm xử lý `onClick` được truyền tới `<button>`.
409
+
2. Hàm xử lý đó, được định nghĩa trong `Button`:
410
+
* Gọi `e.stopPropagation()`, ngăn sự kiện nổi bọt xa hơn.
411
+
* Gọi hàm `onClick`, một prop được truyền từ component `Toolbar`.
412
+
3. Hàm đó, được định nghĩa trong component `Toolbar`, hiển thị alert riêng của button.
413
+
4. Vì sự lan truyền đã bị dừng, hàm xử lý `onClick` của `<div>` cha *không* chạy.
414
414
415
-
As a result of `e.stopPropagation()`, clicking on the buttons now only shows a single alert (from the `<button>`) rather than the two of them (from the `<button>` and the parent toolbar `<div>`). Clicking a button is not the same thing as clicking the surrounding toolbar, so stopping the propagation makes sense for this UI.
415
+
Như một hệ quả của `e.stopPropagation()`, nhấn vào các nút giờ chỉ hiện một alert duy nhất (từ `<button>`) chứ không phải hai alert (từ `<button>` và từ `<div>` cha). Nhấn một nút không giống như việc nhấn vào xung quanh thanh công cụ, nên việc dừng sự lan truyền hợp lý cho giao diện này.
#### Các sự kiện trong giai đoạn bắt {/*capture-phase-events*/}
420
420
421
-
In rare cases, you might need to catch all events on child elements, *even if they stopped propagation*. For example, maybe you want to log every click to analytics, regardless of the propagation logic. You can do this by adding `Capture` at the end of the event name:
421
+
Trong một số trường hợp hiếm hoi, bạn có thể cần bắt tất cả sự kiện trên các element con, *kể cả khi chúng đã bị dừng lan truyền*. Ví dụ, có thể bạn muốn log mỗi lượt nhấn để phân tích, bất kể logic lan truyền là gì. Bạn có thể làm thế bằng cách thêm `Capture` vào cuối tên sự kiện:
422
422
423
423
```js
424
-
<div onClickCapture={() => { /* this runs first */ }}>
424
+
<div onClickCapture={() => { /* hàm này chạy trước */ }}>
425
425
<button onClick={e => e.stopPropagation()} />
426
426
<button onClick={e => e.stopPropagation()} />
427
427
</div>
428
428
```
429
429
430
-
Each event propagates in three phases:
430
+
Mỗi sự kiện lan truyền theo ba giai đoạn:
431
431
432
-
1. It travels down, calling all `onClickCapture` handlers.
433
-
2. It runs the clicked element's `onClick` handler.
434
-
3. It travels upwards, calling all `onClick` handlers.
432
+
1. Đi xuống, gọi tất cả hàm xử lý `onClickCapture`.
433
+
2. Chạy hàm xử lý `onClick` của element được nhấn.
434
+
3. Đi lên, gọi tất cả hàm xử lý `onClick`.
435
435
436
-
Capture events are useful for code like routers or analytics, but you probably won't use them in app code.
436
+
Việc bắt các sự kiện có lợi cho code như router hay phân tích, nhưng bạn có thể sẽ không cần sử dụng chúng trong code của ứng dụng.
437
437
438
438
</DeepDive>
439
439
440
-
### Passing handlers as alternative to propagation {/*passing-handlers-as-alternative-to-propagation*/}
440
+
### Truyền các hàm xử lý thay thế cho sự lan truyền {/*passing-handlers-as-alternative-to-propagation*/}
441
441
442
-
Notice how this click handler runs a line of code _and then_ calls the `onClick` prop passed by the parent:
442
+
Hãy để ý cách hàm xử lý `onClick` chạy một dòng code _và sau đó_ gọi prop `onClick` được truyền từ component cha:
443
443
444
444
```js {4,5}
445
445
function Button({ onClick, children }) {
@@ -454,13 +454,13 @@ function Button({ onClick, children }) {
454
454
}
455
455
```
456
456
457
-
You could add more code to this handler before calling the parent `onClick` event handler, too. This pattern provides an *alternative* to propagation. It lets the child component handle the event, while also letting the parent component specify some additional behavior. Unlike propagation, it's not automatic. But the benefit of this pattern is that you can clearly follow the whole chain of code that executes as a result of some event.
457
+
Bạn cũng có thể thêm code vào hàm xử lý trước khi gọi hàm xử lý sự kiện `onClick` cha. Pattern này cung cấp một *phương án thay thế* cho sự lan truyền. Nó cho component con xử lý sự kiện, đồng thời cũng cho component cha chỉ định thêm một số hành vi. Không giống như sự lan truyền, nó không hề tự động. Nhưng lợi ích của pattern này là bạn có thể theo dõi rõ ràng toàn bộ chuỗi code được thực thi do một số sự kiện gây ra.
458
458
459
-
If you rely on propagation and it's difficult to trace which handlers execute and why, try this approach instead.
459
+
Nếu bạn dựa vào sự lan truyền và thấy khó theo dõi hàm xử lý nào thực thi và tại sao, hãy thử phương pháp này xem.
### Ngăn hành vi mặc định {/*preventing-default-behavior*/}
462
462
463
-
Some browser events have default behavior associated with them. For example, a `<form>` submit event, which happens when a button inside of it is clicked, will reload the whole page by default:
463
+
Một số sự kiện trình duyệt có hành vi mặc định gắn liền với chúng. Ví dụ, sự kiện submit của `<form>` xảy ra khi một nút bên trong nó bị nhấn, sẽ mặc định tải lại toàn bộ trang:
464
464
465
465
<Sandpack>
466
466
@@ -481,7 +481,7 @@ button { margin-left: 5px; }
481
481
482
482
</Sandpack>
483
483
484
-
You can call `e.preventDefault()` on the event object to stop this from happening:
484
+
Bạn có thể gọi `e.preventDefault()` trên đối tượng sự kiện để ngăn hành vi này xảy ra:
Don't confuse `e.stopPropagation()` and `e.preventDefault()`. They are both useful, but are unrelated:
508
+
Đừng nhầm lẫn `e.stopPropagation()` và `e.preventDefault()`. Cả hai đều có ích, nhưng không liên quan:
509
509
510
-
* [`e.stopPropagation()`](https://developer.mozilla.org/docs/Web/API/Event/stopPropagation) stops the event handlers attached to the tags above from firing.
511
-
* [`e.preventDefault()` ](https://developer.mozilla.org/docs/Web/API/Event/preventDefault) prevents the default browser behavior for the few events that have it.
510
+
* [`e.stopPropagation()`](https://developer.mozilla.org/docs/Web/API/Event/stopPropagation) không cho các hàm xử lý sự kiện được gắn vào các thẻ trên kích hoạt.
511
+
* [`e.preventDefault()` ](https://developer.mozilla.org/docs/Web/API/Event/preventDefault) ngăn các hành vi mặc định từ trình duyệt của một số ít các sự kiện.
512
512
513
513
## Can event handlers have side effects? {/*can-event-handlers-have-side-effects*/}
0 commit comments