在 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
传递过滤器值,而不是作为依赖项。此外,将 getPerson
和 dispatch
作为依赖项添加到 useCallback
.
注意:getPerson
函数也应该被记忆(通过 useMemo
或 useCallback
)。
const [filter, setFilter] = useState('');
const debounceLoadData = useCallback(
debounce(value => dispatch(getPersons(10, 1, value)), 1000),
[getPersons, dispatch]
);
我发现 useCallback
在去抖动情况下没有用。而是使用 useMemo
为 dispatch
创建固定实例(使用 fixed/variable 输入参数)。
const debouceLoadData = useMemo(() => {
return debounce(f => {
dispatch(getPersons(10, 1, f))
}, 1000)
}, [dispatch])
现在您甚至可以根据需要执行 debounceLoadData(f)。
注意:useCallback
不起作用的原因是,实际上您想要 setState(v)
,v
是一个变量。而且你不想在构建去抖动时调用 dispatch
或 getPersons
。您只想构造实例,例如 () => {}
就是 useMemo
涵盖的内容。
这是一个微妙之处。不过你可以先试试useCallback
我在 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
传递过滤器值,而不是作为依赖项。此外,将 getPerson
和 dispatch
作为依赖项添加到 useCallback
.
注意:getPerson
函数也应该被记忆(通过 useMemo
或 useCallback
)。
const [filter, setFilter] = useState('');
const debounceLoadData = useCallback(
debounce(value => dispatch(getPersons(10, 1, value)), 1000),
[getPersons, dispatch]
);
我发现 useCallback
在去抖动情况下没有用。而是使用 useMemo
为 dispatch
创建固定实例(使用 fixed/variable 输入参数)。
const debouceLoadData = useMemo(() => {
return debounce(f => {
dispatch(getPersons(10, 1, f))
}, 1000)
}, [dispatch])
现在您甚至可以根据需要执行 debounceLoadData(f)。
注意:useCallback
不起作用的原因是,实际上您想要 setState(v)
,v
是一个变量。而且你不想在构建去抖动时调用 dispatch
或 getPersons
。您只想构造实例,例如 () => {}
就是 useMemo
涵盖的内容。
这是一个微妙之处。不过你可以先试试useCallback