javascript - 为什么我的函数无意中执行了两次?
问题描述
我有一个构造函数、get 方法、componentDidMount 和 componentWillUnmount 方法。我只想监听一个滚动事件,并据此调用 get 方法。如果滚动在页面底部,则调用一次 get 方法。就这样。第一个调用,即 componentDidmount(),工作了一次,但是当我向下滚动时,get 方法工作了两次。我不希望它执行不止一次。
这是我的代码:
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()
}
}
这就是我的控制台输出。
1634251341094964000 ----> 一次
1614497980820334000 ----> 两次
1579177573029464600 ----> 两次
. . .
它们来自 get 函数的 console.log(data.next_cursor) 。
解决方案
由于似乎事件被窗口/滚动条多次触发,因此您需要防止代码中的重复调用。有很多方法可以做到这一点,具体取决于上下文和要求。这里有几个选项。
你可以去抖动函数调用。如果您只需要确保它只在特定时间窗口内被调用一次,这将是很好的。
另一种选择是使用state
,以及isLoading
您已经定义的道具:
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});
}
}
}
推荐阅读
- windows - Delphi 7 可以通过 OLE Variant 传递 Int64 值吗?
- python - Django Server启动后如何自动启动其他服务器
- angular - 动态生成组件(Angular 7)以插入 DOM
- python - Python QTableView | 如何在不按住 Ctrl 的情况下通过单击选择多行?
- jquery - 如何将此 Jquery 代码转换为 React JS?
- sql - 带有多个子查询的 SQL 错误 10249 Hive
- android - Android Studio 3.3 升级后,我的 APK 会构建但不会运行
- regex - Groovy 正则表达式命名捕获组必须调用匹配方法?
- java - Markwon 不处理链接
- gps - 室内跟踪系统将如何帮助医院的患者监测?