如何在React中的滚动事件上绑定到_.throttle

时间:2018-03-21 14:02:50

标签: reactjs

如何在React中调用一个调用滚动的函数,该函数使用如下所示的绑定?

this.getElementPosition = this.getElementPosition.bind(this);

到目前为止我的内容如下,但它会返回TypeError: Cannot read property 'bind' of undefined

throttle() {
  _.throttle((this.getElementPosition = this.getElementPosition.bind(this)), 100)
}

componentDidMount() {
  window.addEventListener('scroll', this.throttle)
}

componentWillUnmount() {
  window.removeEventListener('scroll', this.throttle);
}

getElementPosition() {
  var rect = this.elementPosition.getBoundingClientRect();

  if ((rect.top > 0) && (rect.top < (window.innerHeight * 0.75))) {
    this.elementPosition.setAttribute("data-position","in-viewport");
  } else if (rect.top > window.innerHeight) {
    this.elementPosition.setAttribute("data-position","below-viewport");
  } else if (rect.bottom < 0) {
    this.elementPosition.setAttribute("data-position","above-viewport");
  }
}

render() {
  return (
    <div ref={(element) => { this.elementPosition = element; }} data-position="below-viewport">
    </div>
  );
}

3 个答案:

答案 0 :(得分:1)

你需要绑定这个&#39;在构造函数中也是如此。

constructor() {
  super();
  this.throttle = this.throttle.bind(this);
  this.getElementPosition = this.getElementPosition.bind(this)
}

throttle() {
 _.throttle(this.getElementPosition, 100)
}

答案 1 :(得分:1)

这是我的方法

import React, { Component } from 'react'
import throttle from 'lodash.throttle'

class Scroller extends Component {
  constructor(props) {
    super(props)
    this.element = React.createRef()
    this.onScroll = this.onScroll.bind(this)
    this.onScrollThrottled = throttle(this.onScroll, 300)
  }

  componentDidMount() {
    this.element.current.addEventListener('scroll', this.onScrollThrottled)
  }

  componentWillUnmount() {
    this.element.current.removeEventListener('scroll', this.onScrollThrottled)
  }

  onScroll(e) {
    console.log(e.target.scrollTop)
  }

  render() {
    return (
      <div ref={this.element}>
        ...
      </div>
    )
  }

}

Lodash throttle返回一个函数,因此用另一个函数(方法类)包装它会迫使您调用它

onScrollThrottled() { return throttle(this.onScroll, 300) }
componentDidMount() {
  this.element.current.addEventListener('scroll', this.onScrollThrottled())
}

还有throttle(this.onScroll, 300) !== throttle(this.onScroll, 300),因此您将无法正确退订componentWillUnmount。这就是为什么我改用class属性。另外,我使用了独立版本的lodash节流阀,可以通过npm(see doc

添加
  

npm我-保存lodash.throttle

答案 2 :(得分:0)

按照lodash docs https://lodash.com/docs/4.17.4#throttle尝试这样:

componentDidMount() {
  window.addEventListener('scroll', _.throttle(this.doThrottle, 100))
}

doThrottle = () => {
  this.getElementPosition = this.getPosition()
}

getPosition = () => {
  // stuff
}

请注意doThrottlegetPosition上的箭头功能会将其转换为组件中的隐式bind(this)。最初的问题在于您自己的限制方法,其中this未绑定到您的组件。