Reactjs 为每个类型更改执行的去抖动输入更改
我想添加一个debounce函数,以避免为每个字符启动搜索api:Reactjs 为每个类型更改执行的去抖动输入更改,reactjs,typescript,Reactjs,Typescript,我想添加一个debounce函数,以避免为每个字符启动搜索api: export const debounce = <F extends ((...args: any) => any)>( func: F, waitFor: number, ) => { let timeout: number = 0; const debounced = (...args: any) => { clearTimeout(timeout); setT
export const debounce = <F extends ((...args: any) => any)>(
func: F,
waitFor: number,
) => {
let timeout: number = 0;
const debounced = (...args: any) => {
clearTimeout(timeout);
setTimeout(() => func(...args), waitFor);
};
return debounced as (...args: Parameters<F>) => ReturnType<F>;
};
export const debounce=any)>(
func:F,
等待:号码,
) => {
let timeout:number=0;
const debounced=(…参数:any)=>{
clearTimeout(超时);
setTimeout(()=>func(…args),waitFor);
};
返回取消公告为(…参数:参数)=>ReturnType;
};
Search.tsx:
import React, { useCallback } from "react";
import { useSelector, useDispatch } from "react-redux";
import { getAllTasks } from "./taskSlice";
import { ReturnedTask } from "../../api/tasks/index";
import TextField from "@material-ui/core/TextField";
import Autocomplete from "@material-ui/lab/Autocomplete";
import { AppState } from "../../app/rootReducer";
import { debounce } from "../../app/utils";
const SearchTask = () => {
const dispatch = useDispatch();
const [open, setOpen] = React.useState(false);
const debounceOnChange = useCallback(debounce(handleChange, 400), []);
const { tasks, userId } = useSelector((state: AppState) => ({
tasks: state.task.tasks,
userId: state.authentication.user.userId,
}));
const options = tasks.length
? tasks.map((task: ReturnedTask) => ({ title: task.title }))
: [];
const handleOpen = () => setOpen(true);
const handleClose = () => setOpen(false);
function handleChange(
e: React.ChangeEvent<{}>,
value: string,
) {
const queryParams = [`userId=${userId}`];
if (value.length) {
console.log(value);
queryParams.push(`title=${value}`);
dispatch(getAllTasks(queryParams));
}
}
return (
<Autocomplete
style={{ width: 300 }}
open={open}
onOpen={handleOpen}
onClose={handleClose}
onInputChange={(e: React.ChangeEvent<{}>, value: string) =>
debounceOnChange(e, value)}
getOptionSelected={(option, value) => option.title === value.title}
getOptionLabel={(option) => option.title}
options={options}
renderInput={(params) => (
<TextField
{...params}
label="Search Tasks"
variant="outlined"
InputProps={{ ...params.InputProps, type: "search" }}
/>
)}
/>
);
};
export default SearchTask;
import React,{useCallback}来自“React”;
从“react-redux”导入{useSelector,useDispatch};
从“/taskSlice”导入{getAllTasks};
从“../../api/tasks/index”导入{ReturnedTask}”;
从“@material ui/core/TextField”导入TextField;
从“@material ui/lab/Autocomplete”导入自动完成;
从“../../app/rootReducer”导入{AppState}”;
从“./../app/utils”导入{debounce}”;
const SearchTask=()=>{
const dispatch=usedpatch();
const[open,setOpen]=React.useState(false);
const debounceOnChange=useCallback(debounce(handleChange,400),[]);
const{tasks,userId}=useSelector((state:AppState)=>({
任务:state.task.tasks,
userId:state.authentication.user.userId,
}));
const options=tasks.length
?tasks.map((task:ReturnedTask)=>({title:task.title}))
: [];
const handleOpen=()=>setOpen(true);
const handleClose=()=>setOpen(false);
功能手柄更换(
e:React.change事件,
值:字符串,
) {
常量queryParams=[`userId=${userId}`];
if(值.长度){
console.log(值);
push(`title=${value}`);
调度(getAllTasks(queryParams));
}
}
返回(
去BounceOnChange(e,值)}
getOptionSelected={(选项,值)=>option.title==value.title}
getOptionLabel={(option)=>option.title}
选项={options}
renderInput={(参数)=>(
)}
/>
);
};
导出默认搜索任务;
组件的实际行为是为每个类型的字符启动api。我只想在一段时间后启动api。如何修复它?正如@Jayce444在评论中提到的,上下文并没有在每次调用和函数之间保留
export const debounce = <F extends ((...args: any) => any)>(
func: F,
waitFor: number,
) => {
let timeout: NodeJS.Timeout;
return (...args: any) => {
clearTimeout(timeout);
timeout = setTimeout(() => func(...args), waitFor);
};
};
export const debounce=any)>(
func:F,
等待:号码,
) => {
let timeout:NodeJS.timeout;
返回(…参数:任意)=>{
clearTimeout(超时);
timeout=setTimeout(()=>func(…args),waitFor);
};
};
尽管您使用useCallback
记忆对去Bounce函数的引用,但在实际的去Bounce函数本身中,您有const debounced=(…)…
,这意味着每次调用该函数时都将重新创建该函数。您应该使用闭包之类的东西来保留函数调用之间的上下文,这样就不会在每次重新渲染时创建一个新的超时函数。谷歌到处寻找去Bouncing的vanilla JS实现,了解如何实现去Bouncinglooks@Jayce444谢谢你的评论。我通过更新函数解决了这个问题。