react hooks写法中使用防抖节流

在Class继承写法中,我们的防抖节流都是这样写的

import debounce from 'lodash/debounce';

export default class Search extends Component {
    constructor(props) {
      super(props)
      this.handleSearch = debounce(this.handleSearch, 500);
    }
    handleSubmit = (e) => {
        e.preventDefault();
        this.handleSearch();
    }
    handleSearch = () => {
    ...
    }
    render() {
        return (
            <form onSubmit={this.handleSubmit}><form>
        )
    }
}

改写成hooks是这样

import React, {useState} from "react";
import debounce from 'lodash/debounce';
const sendQuery = (query) => console.log(`Querying for ${query}`);
const Search = () => {
  const [userQuery, setUserQuery] = useState("");
  const delayedQuery = debounce(q => sendQuery(q), 500);
  const onChange = e => {
    setUserQuery(e.target.value);
    delayedQuery(e.target.value);
  };
  return (
    <div>
      <label>Search:</label>
      <input onChange={onChange} value={userQuery} />
    </div>
  );
}

但这样子做防抖函数并没有发挥作用,仅仅是把反应时间延后了500毫秒。这是因为函数组件每次渲染结束之后,内部的变量都会被释放,重新渲染时所有的变量会被重新初始化,产生的结果就是每一次都注册和执行了setTimeout函数。想要得到正确的运行结果,必须以某种方式存储那些本会被删除的变量和方法的引用。很遗憾,没办法直接使用useState去存储,我们可以使用useRef和useCallback我们可以更简单的去解决这个问题:

const SearchFixed = () => {
  const [userQuery, setUserQuery] = useState("");
  const delayedQuery = useCallback(debounce(q => sendQuery(q), 500), []);
  const onChange = e => {
    setUserQuery(e.target.value);
    delayedQuery(e.target.value);
  };
  return (
    <div>
      <label>Search Fixed:</label>
      <input onChange={onChange} value={userQuery} />
    </div>
  );
};

或者使用useRef

const SearchFixed = () => {
  const [userQuery, setUserQuery] = useState("");
  const delayedQuery = useRef(debounce(q => sendQuery(q), 500)).current;
  const onChange = e => {
    setUserQuery(e.target.value);
    delayedQuery(e.target.value);
  };
  return (
    <div>
      <label>Search Fixed:</label>
      <input onChange={onChange} value={userQuery} />
    </div>
  );
};

也可以自定义hook去解决

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值