Reputation: 213
I have a constructor, get method, componentDidMount and componentWillUnmount methods. I want to just listen for a scroll event and, according to that, call the get method. If the scroll is at the bottom of page, the get method is called one time. That's all. The first call, that is componentDidmount(), is working one time but when I scroll down, the get method is working two times. I don't want it to execute more than once.
This is my code:
constructor(props) {
super(props);
cursor = -1
id = auth().currentUser.providerData[0].uid
this.state = {
hits: [],
isLoading: false,
over: false,
firstCall: true
};
this.get = this.get.bind(this)
this.handleScroll = this.handleScroll.bind(this)
}
get() {
this.setState({ isLoading: true });
fetch("/1.1/followers/list.json?user_id=" + id + "&cursor=" + cursor + "", {
headers: {
'Authorization': 'MyToken',
}
}).then(response => response.json())
.then(data => {
if (data.next_cursor == 0) {
this.setState({ isLoading: false })
this.setState({ over: true })
} else {
this.setState({ hits: this.state.hits.concat(data.users), isLoading: false })
cursor = data.next_cursor
console.log(data.next_cursor)
}
}).catch(error => {
return
})
}
componentDidMount() {
this.get()
window.addEventListener('scroll', this.handleScroll);
}
componentWillUnmount() {
window.removeEventListener('scroll', this.handleScroll);
}
handleScroll(event) {
if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight) {
this.get()
}
}
And that is my console output.
1634251341094964000 ----> one time
1614497980820334000 ----> two time
1579177573029464600 ----> two time
. . .
They are coming from console.log(data.next_cursor) at the get function.
Upvotes: 0
Views: 284
Reputation: 5785
Since it seems like the event gets fired multiple times by the window / scrollbar, you'll need to guard against duplicate calls in your code. There are many ways to do this, depending on the context and the requirements. Here are a couple options.
You could debounce the function call. This would be good if you just need to make sure it is only called once within a certain time window.
Another option is to use state
, and theisLoading
prop you've already defined:
get(){
if(!this.state.isLoading){
//use the setState callback param here so we don't run into async issues
this.setState({isLoading: true}, () => {
... the rest of your logic ...
//get is finished (either success or failure)
this.setState({isLoading: false});
}
}
}
Upvotes: 1