When implementing UI/device event behavior (key holds, scrolling, resize compensation), treat the logic as an explicit state machine with clear invariants: track the source of events, preserve correctness across async updates, and don’t infer “intent” from ambiguous signals.
Apply this standard:
Sketch of the pattern (scroll example):
const ourScrollTarget = useRef<number | null>(null);
const handleScroll = () => {
if (ourScrollTarget.current !== null) {
const arrived = Math.abs(viewport.scrollTop - ourScrollTarget.current) <= 1;
if (arrived) ourScrollTarget.current = null;
else if (pinnedRef.current) return; // ignore while pinned during our scroll
}
const distance = distanceFromBottom(viewport);
setPinned(distance <= PINNED_THRESHOLD_PX);
};
const scrollToBottom = () => {
ourScrollTarget.current = viewport.scrollHeight;
setPinned(true);
viewport.scrollTo({ top: viewport.scrollHeight, behavior: "smooth" });
};
This reduces subtle correctness bugs (accidental unpinning, scroll drift under streaming, misclassifying taps) by aligning the algorithm with the real event stream and preserving the same invariants throughout the lifecycle.