在 React 中使用 debounce 进行搜索的正确方法

Proper Way of Searching in React with debounce

我在 lodash 中使用 debounce 搜索时遇到问题。我正在使用 React、Material Ui 和 formik。 它说 TypeError: Expected a function

const debounceLoadData = useCallback( debounce(dispatch(getPersons(10, 1, filter)), 1000), [] );

const [filter, setFilter] = useState("");

const debounceLoadData = useCallback(
  debounce(dispatch(getPersons(10, 1, filter)), 1000),
  []
);

const onSearchVoter = (value) => {
  setFilter(value);
  debounceLoadData(value);
};

<Autocomplete
  value={values.voter_id}
  options={persons ? persons : []}
  getOptionSelected={(option, value) => option === value}
  getOptionLabel={(person) =>
    person
      ? [person?.fname, person?.mname, person?.lname].filter(Boolean).join(" ")
      : ""
  }
  onChange={(e, value) => {
    setFieldValue("voter_id", value ? value : "");
  }}
  onInputChange={async (event, value) => {
    onSearchVoter(value);
  }}
  renderInput={(params) => (
    <TextField
      {...params}
      name="voter_id"
      label="Voter"
      variant="outlined"
      onBlur={handleBlur}
      helperText={touched.voter_id ? errors.voter_id : ""}
      error={touched.voter_id && Boolean(errors.voter_id)}
      fullWidth
    />
  )}
/>;

_.debounce() 函数需要另一个函数,而不是调用 dispatch 的结果。您应该将调度调用包装在箭头函数中,并通过参数 value 传递过滤器值,而不是作为依赖项。此外,将 getPersondispatch 作为依赖项添加到 useCallback.

注意:getPerson 函数也应该被记忆(通过 useMemouseCallback)。

const [filter, setFilter] = useState('');

const debounceLoadData = useCallback(
  debounce(value => dispatch(getPersons(10, 1, value)), 1000),
  [getPersons, dispatch]
);

我发现 useCallback 在去抖动情况下没有用。而是使用 useMemodispatch 创建固定实例(使用 fixed/variable 输入参数)。

  const debouceLoadData = useMemo(() => {
    return debounce(f => {
      dispatch(getPersons(10, 1, f))
    }, 1000)
  }, [dispatch])

现在您甚至可以根据需要执行 debounceLoadData(f)。

注意:useCallback 不起作用的原因是,实际上您想要 setState(v)v 是一个变量。而且你不想在构建去抖动时调用 dispatchgetPersons 。您只想构造实例,例如 () => {} 就是 useMemo 涵盖的内容。

这是一个微妙之处。不过你可以先试试useCallback