開發隨筆:在react中使用帶參的防抖節流回調

12. 在react中使用防抖和節流

1. 原理

爲什麼要使用防抖節流,以及防抖節流的原理可以細看

防抖和節流

2. 在React中使用防抖節流錯誤的例子
import React from "react";
import { debounce } from "lodash";

export function ErrorInput() {
  const onChange = e => {
    console.log(e.target.value);
  };

  return <input onChange={debounce(onChange, 500)} />;
}

上述代碼看上去沒啥問題,但是我們實際在輸入框中改變Input的值的時候會出現以下報錯

在這裏插入圖片描述

這裏存在的問題是,因爲event事件是同步的,而通過debounce之後,會將多次的事件合併爲一次,進行執行,因此該event性質會被改變不再是同步傳過來的變量了,因此會有該警告

3. 解決辦法

方法一:添加e.persist()。如果按照提示,在調用的函數中添加e.persist(),確實能夠消除該報錯,但是接下來的問題是event.target可能會是null,那麼如果我們在接下來的業務代碼中需要使用到e.target.value就會由問題。因此這個方法不太推薦。

方法二:利用傳參的方法來實現。直接上代碼

import _ from "lodash";
import React, { Component } from "react";

function Search() {
  const _handle = value => {
    console.log(value);
  };

  const debounceHandler = _.debounce(_handle, 500);

  const onChange = e => {
    debounceHandler(e.target.value);
  };

  return (
    <div>
      Search:
      <input onChange={onChange} />
    </div>
  );
}

export default Search;

要點總結:

  1. 設置一個同步處理函數_handle,該函數接受傳來的value值,下面就和普通的回調函數一樣執行業務代碼即可
  2. 通過一個debounceHandler,調用bounce來生成一個防抖的回調函數
  3. 定義一個綁定的onChange函數,並指定傳參到debounceHandler中即可

**注意:**這個debonceHandler不能定義在onChange函數內!!!!!非常重要。因爲lodash的debounce是通過閉包來維護一個內部的timer,來控制當指定時間段內,多次事件合併。如果定義在onChange內,每次都會多產生一個閉包環境,仍然會導致多個回調函數被觸發,達不到防抖的效果,切忌切忌

4. 結果展示

在這裏插入圖片描述

上述代碼請查看codesandbox demo

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章