Reputation: 167
I'm looking for a help with how to make a chunk load, when the user scrollbar, and reach a specific div, then it shoul run a function one time, but the code run multiples time:
async function loadMore(){
console.log('i load more');
}
window.addEventListener('scroll', async (event) => {
const {
scrollTop,
scrollHeight,
clientHeight
} = document.documentElement;
if (scrollTop + clientHeight >= scrollHeight - 1 ) {
document.getElementById('final').style.height = '3000px'
let msg = await loadMore()
console.log('i finish')
document.getElementById('final').style.height = '30px'
}
}, {
passive: true
});
return (
<div id='final'>
<Image src="/ajax-loader.gif" width={60} height={60} alt="loader spinner"></Image>
</div>
)
Upvotes: 0
Views: 953
Reputation: 5416
Few things:
useEffect
.
useEffect
else you will again end up with a lot of event listenersdebounce
. You can choose other implementations if you want or create your own one.import debounce from "lodash.debounce";
function YourComponent() {
async function loadMore(){
console.log('i load more');
}
// "useEffect" so that you don't add a new event listener
// on every render
useEffect(() => {
const onScroll = async (event) => {
// Whatever you want to do when user scrolls
}
// This is the debounced "onScroll" function instance
// "500" specifies that it will be debounced for 500 milliseconds
const debouncedOnScroll = debounce(onScroll, 500);
// Attach the event listener to window
window.addEventListener('scroll', debouncedOnScroll);
// Cleanup the event listener when component unmounts or
// when the "useEffect" runs again.
return () => window.removeEventListener('scroll', debouncedOnScroll);
}, []);
return (
<div id='final'>
{/* Rest of your JSX */}
</div>
)
}
Upvotes: 1
Reputation: 11
trigger window event listener inside useEffect
make sure to cleanup the event: return () => window.removeEventListener('scroll', callback);
Upvotes: 0