In my app, for every intersection, fetch 10 messages with timestamps that are less/earlier than the date request, then unshift them into messages
array. The value of the date request is the timestamp of the first item in messages
state. Here's the IntersectionObserver code:
const MessagesContainer = forwardRef((props, ref) => {
// ...
const messages = useSelector(state => state.messages)
const dispatch = useDispatch()
const ioCallback = useCallback((entries, observer) => {
if (entries[0].isIntersecting) {
console.log(messages[0].timestamp)
setLoading(true)
axios.post('/api/messages', { date: messages[0].timestamp })
.then(response => {
if (response.data.messages.length) {
dispatch({
type: 'ADD_TO_LIST',
name: 'messages',
payload: response.data.messages
})
ref.current.scrollTo(0, ref.current.scrollHeight / 3)
}
else {
observer.unobserve(target.current)
}
setLoading(false)
})
}
}, [messages])
useEffect(() => {
const ioOptions = {
root: ref.current,
rootMargin: '0px',
threshold: 1.0
}
const observer = new IntersectionObserver(ioCallback, ioOptions)
if (target && target.current) {
observer.observe(target.current)
}
}, [ioCallback])
// ...
})
You would notice the console.log(messages[0].timestamp)
in ioCallback()
. For every intersection, log the timestamp of the first item in messages
state.
The first intersection/scroll is okay, it logs:
2020-06-24T20:02:41.214Z
But the next one logs the old value and the new value:
2020-06-24T20:02:41.214Z
2020-06-24T20:02:19.761Z
I need to know how to prevent useCallback from getting the old state value.