'React: I can't get updated state values in the onScroll function
Task: I am trying to implement dynamic loading of content when scrolling for a reaction.
I have an onScroll function to listen for a scroll event, which switches the isFetching variable to true when the page is scrolled all the way down. When isFetching === true, the code from useEffect is executed and the content is loaded.
Everything works as it should, but I need to add another condition to onScroll, which is triggered while the amount of loaded data is < the total amount of data.
Problem: I have variables schoolResults and schoolResultsCount, which contain the number of loaded data and the total amount of data, but they are not updated when scrolling, they are always 0 when scrolling.
I understand that I can transfer the function to useEffect or use a condition in useEffect and everything will work as I need. But I don't understand why the updated values of external variables are not available in the function?
Thank you for your help!
export default function Results(props: Props) {
const location = useLocation();
const [isLoading, setLoading] = useState<boolean>(false);
const [isFetching, setFetching] = useState<boolean>(false);
const [schoolResults, setSchoolResults] = useState<SchoolEvent[]>([]);
const [schoolResultsCount, setSchoolResultsCount] = useState<number>(0);
const [currentPage, setCurrentPage] = useState<number>(1);
const { school } = props;
const { id: schoolId } = school;
useEffect(() => {
setLoading(true);
const promises = [
getSchoolEvents(schoolId, getFilterForAllSchoolResults()),
getSchoolEventsCount(schoolId, getFilterForAllSchoolResults())
];
Promise.all(promises).then(([events, eventsCountObj]) => {
setSchoolResults(events);
setSchoolResultsCount(eventsCountObj.count);
setLoading(false);
});
}, [location.search]);
useEffect(() => {
if (isFetching) {
const queryFilter = {
...getFilterForAllSchoolResults(),
skip: currentPage * LIMIT
};
getSchoolEvents(schoolId, queryFilter)
.then((events) => {
setSchoolResults([...schoolResults, ...events]);
setCurrentPage(prevState => prevState + 1);
})
.finally(() => setFetching(false));
}
}, [isFetching]);
useEffect(() => {
document.addEventListener('scroll', onScroll);
return function () {
document.removeEventListener('scroll', onScroll);
}
}, []);
const onScroll = (event: Event) => {
const { target } = event;
const scrollHeight = propz.get(target, ['documentElement', 'scrollHeight']);
const scrollTop = propz.get(target, ['documentElement', 'scrollTop']);
const windowInnerHeight = window.innerHeight;
const isBottomOfPage = scrollHeight - (scrollTop + windowInnerHeight) < 100;
// console.log('schoolResults', schoolResults.length); //The value is 0. Not updated. Why?
// console.log('schoolResultsCount', schoolResultsCount); // The value is 0. Not updated. Why?
if (isBottomOfPage /*&& schoolResults.length > schoolResultsCount*/) {
setFetching(true);
};
};
if (isLoading) {
return <Loader />;
}
return (//Some JSX)
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
