React 涉及e.target时候,使用debounce节流函数

摘要:在一个input搜索框中输入文本,如果2s内可能会有很多次input的onChange事件,每次都触发一个API请求,明显不合理,所以此时需要debounce节流函数,2s之内的所有输入只会请求一次API

举例场景: 

在一个input搜索框中输入文本,如果2s内可能会有很多次input的onChange事件,每次都触发一个API请求,明显不合理,所以此时需要debounce节流函数,2s之内的所有输入只会请求一次API,做到交互层面的优化。

为了缩小关注点,示例直接使用loadsh的debounce函数。也直接使用了类的示例属性方法(可用过babel支持,因为实在不喜欢写过多的bind)


==直接上正确代码:==

import React from 'react'
import {debounce} from 'lodash'

export default class InputDebounce extends React.Component {
  constructor() {
    super()
    this.doSearchAjax = debounce(this.doSearchAjax, 2000)
  }

  handleInputSearch = e => {
    this.doSearchAjax(e.target.value)
  }

  doSearchAjax = value => {
    console.log('执行AJAX搜索', value)
  }

  render() {
    return (
      <div>
        <h4>e.target 结合 debounce 使用</h4>
        <input type="text" onChange={this.handleInputSearch} />
      </div>
    )
  }
}


再来看常见的错误代码示例

一、直接使用debounce函数包裹事件函数

报错: Uncaught TypeError: Cannot read property 'value' of null

原因分析: 涉及到React中的合成事件,详见React合成事件,debounce包装后的回调函数,是个异步事件,即e.target为null了

解决方案: 使用e.persist()实现对事件的引用保留

import React from 'react'
import {debounce} from 'lodash'

export default class InputDebounce extends React.Component {
  handleInputSearch = e => {
    this.doSearchAjax(e.target.value)
  }

  doSearchAjax = value => {
    console.log('执行AJAX搜索')
  }

  render() {
    return (
      <div>
        <h4>e.target 结合 debounce 使用</h4>
        <input type="text" onChange={debounce(this.handleInputSearch, 2000)} />
      </div>
    )
  }
}


二、使用了e.persist(),但是 debounce 包含的函数并不会执行

import React from 'react'
import {debounce} from 'lodash'

export default class InputDebounce extends React.Component {
  handleInputSearch = e => {
    // 对原有事件进行保留
    e.persist()
    debounce(() => {
      // 函数并不会执行
      this.doSearchAjax(e.target.value)
    }, 2000)
  }

  doSearchAjax = value => {
    console.log('执行AJAX搜索')
  }

  render() {
    return (
      <div>
        <h4>e.target 结合 debounce 使用</h4>
        <input type="text" onChange={this.handleInputSearch} />
      </div>
    )
  }
}

这时候,需要将异步执行的函数抽离出来,即开头的正确代码。正确代码里面并未使用e.persist(),因为没有必要,onChange函数并非是被debounce函数包装的。


本文内容仅供个人学习、研究或参考使用,不构成任何形式的决策建议、专业指导或法律依据。未经授权,禁止任何单位或个人以商业售卖、虚假宣传、侵权传播等非学习研究目的使用本文内容。如需分享或转载,请保留原文来源信息,不得篡改、删减内容或侵犯相关权益。感谢您的理解与支持!

链接: https://shenqiku.cn/article/FLY_4878