useEffect chạy sau khi trình duyệt đã vẽ, nên người dùng kịp thấy một khung hình tooltip ở vị trí sai rồi mới nhảy. useLayoutEffect chạy sau khi DOM được cập nhật nhưng trước khi vẽ, nên việc đo và chỉnh vị trí gộp vào cùng một khung hình.
jsx
useLayoutEffect(() => {
const { height } = ref.current.getBoundingClientRect()
setFlipped(buttonTop < height) // measured before paint
}, [])Cảnh báo "useLayoutEffect does nothing on the server" xuất hiện vì trên server không có DOM để đo và không có lượt vẽ nào, nên React bỏ qua hook này và nhắc rằng markup ban đầu sẽ không có kết quả đo.
Cách xử lý:
- Render nội dung ban đầu không cần đo (ẩn tooltip, hoặc đặt vị trí mặc định) rồi để
useLayoutEffectchỉnh sau khi hydrate. Cảnh báo mất và không lệch hydration. - Với component chỉ chạy phía client, tải động với
ssr: false. - Chỉ dùng
useLayoutEffectcho việc đo đạc và điều chỉnh layout đồng bộ. Nó chặn lượt vẽ, đặt logic nặng vào đây sẽ làm chậm hiển thị.