Có một bug React rất ngầm mà nhiều lập trình viên gặp phải mà không nhận ra lý do tại sao.
js
const filters = [selectedValue]
Nhưng nếu filters được sử dụng bên trong một dependency array của useEffect hoặc useCallback…
👉 Component của bạn có thể bắt đầu re-render không ngừng.
js
[1] === [1] // false
{} === {} // false
Object và array được so sánh theo tham chiếu, chứ không phải theo giá trị.
Mỗi khi component của bạn render:
js
const filters = [selectedValue]
JavaScript sẽ tạo ra một array hoàn toàn mới trong bộ nhớ.
Ngay cả khi selectedValue không thay đổi,
tham chiếu vẫn khác nhau.
And đối với React, điều đó có nghĩa là: dependency đã thay đổi.
Một pattern phổ biến trông giống như thế này:
js
const filters = [selectedValue]
const fetchData = useCallback(() => {
dispatch({ filters })
}, [filters])
useEffect(() => {
fetchData()
}, [fetchData])
-
1.
Render → array mới được tạo
-
2.
filters thay đổi → tạo lại fetchData mới
-
3.
fetchData thay đổi → kích hoạt useEffect
-
4.
useEffect chạy → dispatch action
-
5.
State cập nhật → re-render
-
6.
Quay lại bước 1
-
Kiểu dữ liệu nguyên thủy (string, number, boolean) → so sánh theo giá trị → an toàn
-
Object / Array / Function → so sánh theo tham chiếu → rủi ro
Bất cứ khi nào bạn thấy những thứ này bên trong một lần render:
Hãy ổn định tham chiếu bằng cách sử dụng useMemo:
js
const filters = useMemo(() => {
return [selectedValue]
}, [selectedValue])
Hoặc tránh tạo các object/array mới nếu bạn thực sự không cần đến chúng.
Hy vọng bài viết này giúp ích cho bạn! :)