Đặt một phần tử sentinel ở cuối danh sách và quan sát nó; sentinel lọt vào tầm ngắm thì tải trang tiếp theo.
js
const io = new IntersectionObserver(
([entry]) => {
if (entry.isIntersecting && !loadingRef.current) loadMore()
},
{ root: scrollBoxRef.current, rootMargin: '400px 0px', threshold: 0 },
)
io.observe(sentinelRef.current)root: khung tham chiếu.null= viewport; nếu danh sách cuộn trong mộtdivcóoverflow: autothì phải truyền chính div đó, không thì callback không bao giờ bắn.rootMargin: nới rộng vùng quan sát.400pxnghĩa là tải trước khi người dùng thật sự chạm đáy, giảm cảm giác chờ. Chỉ nhận đơn vị px/%, không nhậnrem.threshold: tỉ lệ phần tử phải lộ ra để kích hoạt. Với sentinel mỏng thì0là đủ; với tracking hiển thị quảng cáo mới cần0.5hoặc mảng nhiều mốc.
Bẫy hay gặp:
- Bắn nhiều lần: sentinel còn trong tầm ngắm sau khi thêm item → phải có cờ loading hoặc unobserve trong lúc fetch.
- Sentinel cao 0px và không có nội dung có thể bị coi là không giao nhau; cho nó chiều cao tối thiểu.
- Callback chạy bất đồng bộ, gom theo batch, không phải mỗi pixel cuộn — đây chính là lý do nó nhẹ hơn nghe scroll.
- Nhớ io.disconnect() khi unmount, và tạo lại observer nếu root đổi.