【问题标题】:Why is my function unintentionally executing two times?为什么我的函数无意中执行了两次?
【发布时间】:2020-05-05 04:19:19
【问题描述】:

我有一个构造函数、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)。

【问题讨论】:

  • 使用onScrollBeginDrag怎么样?
  • @Yossi 我以前从未听说过。我不确定它是否已经滚动。我将搜索 onScrollBeginDrag。
  • 您是否尝试过使用断点或console.log 来确定@​​987654322@ 在this.get() 之前发生了什么?我的猜测是您从满足您的条件的窗口中获得了多个滚动事件。我不是滚动条方面的专家,但如果在您到达页面底部时多次触发事件(事件循环比人类反应快得多),我不会感到惊讶。
  • @BrianS 是的,你是对的。 useBottomScrollListener(console.log('asd')) 在handleScroll 上工作了两次。你知道我怎样才能只工作一次吗?

标签: javascript reactjs firebase react-native components


【解决方案1】:

由于窗口/滚动条似乎多次触发了该事件,因此您需要防止代码中的重复调用。有很多方法可以做到这一点,具体取决于上下文和要求。这里有几个选项。

你可以debounce the function call。如果您只需要确保它只在某个时间窗口内被调用一次,这将是很好的。

另一种选择是使用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});
       }
    }
}

【讨论】:

    猜你喜欢
    • 2020-02-23
    • 1970-01-01
    • 2015-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-16
    • 1970-01-01
    • 2011-12-01
    相关资源
    最近更新 更多