Đó là 2 React hooks, useEffect và useLayoutEffect, chúng hoạt động khá giống nhau.
Thậm chí cách code của chúng thật sự giống nhau.
useEffect(() => {
// do side effects
return () => /* cleanup */
}, [dependency, array]);useLayoutEffect(() => {
// do side effects
return () => /* cleanup */
}, [dependency, array]);
Nhưng chúng không hoàn toàn giống nhau. Cùng tiếp tục đọc để xem chúng khác nhau những gì nhé! (Đa số bạn thường dùng useEffect)
Sự khác nhau giữa useEffect và useLayoutEffect
Tất cả nằm ở thời gian
useEffect chạy bất đồng bộ và sau một render được hiện lên màn hình
Trình tự sẽ là:
- Bạn gây ra một event render (thay đổi state, hoặc re-renders từ cha)
- React render Component của bạn (Gọi nó)
- Màn hình được cập nhật UI
- Cuối cùng useEffect chạy
useLayoutEffect, sẽ chạy khác thứ tự, nó chạy đồng bộ sau một render và trước khi màn hình được cập nhật UI. Trình tự là:
- Bạn gây ra một event render
- React render Component của bạn
- useLayoutEffect chạy, và React đợi đến khi nào nó finish.
- Màn hình được cập nhật UI
99% trường hợp sẽ dùng useEffect
Phần lớn trường hợp đồng bộ một số state hoặc props mà nó không cần xảy ra ngay hoặc không cập nhật giao diện ngay
Giống như nếu bạn fetching data, kết quả sẽ không thay đổi ngay lập tức
Hoặc nếu bạn cài đặt một event handler
Hoặc nếu bạn reset một số state khi một modal dialog mở hoặc đóng
Phần lớn trường hợp, useEffect sẽ được dùng
Khi nào dùng useLayoutEffect
Vậy khi nào ta sẽ dùng useLayoutEffect?
Nếu Component của bạn bị giật khi state được cập nhật. Như trong trường hợp, Nó render trong trạng thái state lần đầu và sau đó re-render lại tức thì với trạng thái state cuối cùng - đó là trường hợp tốt để bạn chuyển sang dùng useLayoutEffect.
Dưới đây là ví dụ bạn có thể nhìn thấy những gì tôi nói ở trên.
Khi bạn click vào page, state sẽ thay đổi giá trị ngay (value sẽ = 0), khi re-render component, và khi nào effect chạy - chúng ta sẽ set một giá trị random, và re-render trở lại.
Kết quả là hai render ra liên tiếp và cảm giác nhấp nháy nếu ta sử dụng useEfffect và không nhấp nháy nếu ta dùng useLayoutEffect.
Thử 2 ví dụ ở 2 link này để hiểu rõ hơn nhé!
useLayoutEffect version và version with useEffect.
Chú ý rằng useLayoutEffect chỉ cập nhật UI một lần mặc dù Component render 2 lần. Mặt khác, useEffect thì UI sẽ render 2 lần, vì vậy chúng ta sẽ thấy màn hình giật khi giá trị nó là 0 sau đó lại được set giá trị mới ngay lập tức.
Nên dùng useEffect hay useLayoutEffect?
Phần lớn trường hợp, useEffect là lựa chọn đúng. Nếu code của bạn xảy ra trường hợp giật, thay sang useLayoutEffect sẽ giúp bạn giải quyết vấn đề này
Bởi vì useLayoutEffect là đồng bộ. app của bạn sẽ không cập nhật UI đến khi effect hoàn thành... Nó có thể là nguyên nhân xảy ra vấn đề về performance nếu bạn có những đoạn code xử lý chậm trong effect.