【问题标题】:debounce and react window resize this reference issuedebounce and react window resize this reference issue
【发布时间】:2019-03-24 06:38:43
【问题描述】:

我正在使用 react 和 lodash 的 debounce 方法。我遇到的问题是当用户调整窗口大小时更新状态。

我遇到的问题是,当用户在此函数中调整窗口大小时,this 指的是window,而不是组件:

window.addEventListener('resize', this.delayedCallback)

我尝试设置const that = this 等,但无法获得正确的范围。有谁知道如何解决这个问题?

见下面的代码:

class Card extends Component {

  constructor(props) {
    super(props)
    this.state = {
      cardElWidth: null
    }
    this.delayedCallback = debounce(this.setCardWidth, 1000);
    this.CardEl = React.createRef()
  }

  componentDidMount () {
    this.setCardWidth()
    window.addEventListener('resize', this.delayedCallback)
  }

  setPlayerCardWidth() {
    this.setState({
      cardElWidth: this.CardEl.current.offsetWidth
    })
  } ... rest of code

【问题讨论】:

    标签: javascript reactjs ecmascript-6 this lodash


    【解决方案1】:

    在构造函数中将setCardWidth方法绑定到this

    constructor(props) {
      super(props)
      this.state = {
        cardElWidth: null
      }
      this.setCardWidth = this.setCardWidth.bind(this)
      this.delayedCallback = debounce(this.setCardWidth, 1000)
      this.CardEl = React.createRef()
    }
    

    或者直接在去抖动表达式中绑定,甚至更短:

    constructor(props) {
      super(props)
      this.state = {
        cardElWidth: null
      }
      this.delayedCallback = debounce(this.setCardWidth.bind(this), 1000)
      this.CardEl = React.createRef()
    }
    

    您可以将setCardWidth转换为类属性,并使用箭头函数自动绑定到this,而不是在构造函数中使用bind。

    注意:这需要babel的plugin-proposal-class-properties

    setPlayerCardWidth = () => {
      this.setState({
        cardElWidth: this.CardEl.current.offsetWidth
      })
    }
    

    如果你使用类属性,你也可以删除构造函数:

    class Card extends Component {
      state = {
        cardElWidth: null
      }
    
      CardEl = React.createRef()
    
      componentDidMount() {
        this.setCardWidth()
        window.addEventListener('resize', this.delayedCallback)
      }
    
      componentWillUnmount() {
        window.removeEventListener('resize', this.delayedCallback)
      }
    
      delayedCallback = debounce(this.setCardWidth, 1000)
    
      setPlayerCardWidth = () => {
        this.setState({
          cardElWidth: this.CardEl.current.offsetWidth
        })
      }
    }
    

    【讨论】:

    • 可爱,就是那个!为此欢呼!我会在可以的时候给你绿色的勾号。我也知道:-D
    • 你打算用什么方法?
    • 箭头函数一,别问我为什么,出于某种原因我更喜欢在构造函数中绑定
    • 我也更喜欢那个。它更干净,并且大多数时候您可以完全删除构造函数(参见代码中的示例)。
    猜你喜欢
    • 1970-01-01
    • 2016-07-04
    • 1970-01-01
    • 2016-05-04
    • 2013-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多