Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.4k views
in Technique[技术] by (71.8m points)

reactjs - Lodash debounce isn't preventing dispatch as expected onChange

Currently, I have a list of checkboxes that onChange will make a request to the server to return some data. However, I am using lodash debounce to try and make a request only when the user has stopped selecting the multi-checkbox after a certain amount of time.

Currently, it prevents dispatching straight away but will dispatch after the debounce time has met rather when the user has stopped interacting with the checkboxes. Can someone tell me how I would achieve this or where I am going wrong?

Thanks!

import React, { useContext, useState, useEffect } from 'react';
import { Context } from '../../pages/search-and-results/search-and-results.js';
import debounce from 'lodash.debounce';

const FilterCheckbox = ({ name, value }) => {
  const checkboxContext = useContext(Context);
  const [checked, setChecked] = useState(false);
  const debounceCheckboxSelection = debounce(dispatchCheckbox, 2000);

  function dispatchCheckbox(type, value) {
    checkboxContext.dispatch({
      type: type,
      payload: { value }
    });
  }

  return (
    <Label>
      <FilterInput
        type="checkbox"
        name={name}
        onChange={() => {
          if (checked) {
            debounceCheckboxSelection('REMOVE_SELECTED_PROPERTY_TYPE', value);
            setChecked(false);
            return;
          }
          debounceCheckboxSelection('SET_SELECTED_PROPERTY_TYPE', value);
          setChecked(true);
        }}
        checked={checked}
      />
      {name}
    </Label>
  );
};

export default FilterCheckbox;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Your debounced function is getting created at each re-render, to fix it:

You can use useRef which returns a ref object which will persist for the full lifetime of the component:

const debounceCheckboxSelection = useRef(
  debounce(dispatchCheckbox, 2000);
)

and access its initial value with debounceCheckboxSelection.current:

<FilterInput
  type="checkbox"
  name={name}
  onChange={() => {
    if (checked) {
      debounceCheckboxSelection.current('REMOVE_SELECTED_PROPERTY_TYPE', value);
      setChecked(false);
      return;
    }
    debounceCheckboxSelection.current('SET_SELECTED_PROPERTY_TYPE', value);
    setChecked(true);
  }}
  checked={checked}
/>

Or you can use useCallback will returns a memoized version of the callback that only changes when any of its dependencies change:

const debounceCheckboxSelection = useCallback(
  () => debounce(dispatchCheckbox, 2000), []
)

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...