Javascript React.js中功能组件内部的去抖动
尝试在具有随更改而更新的输入字段的react组件上创建延迟 代码如下:Javascript React.js中功能组件内部的去抖动,javascript,reactjs,react-hooks,lodash,debounce,Javascript,Reactjs,React Hooks,Lodash,Debounce,尝试在具有随更改而更新的输入字段的react组件上创建延迟 代码如下: import React from 'react'; import Input from "@material-ui/core/Input"; import {debounce} from "lodash"; ... const SampleRow = () => { let [newFriend, setNewFriend] = React.useState({na
import React from 'react';
import Input from "@material-ui/core/Input";
import {debounce} from "lodash";
...
const SampleRow = () => {
let [newFriend, setNewFriend] = React.useState({name: '', lastSeen: '', contactIn: ''});
const onAddFriend = debounce(() => {
if(newFriend.name.length === 0){
return;
}
console.log(newFriend.name);
}, 2000);
return (
<TableRow>
<TableCell component="th" scope="row">
<Input
value={newFriend.name}
onChange={(event) => {
setNewFriend({...newFriend, name: event.target.value});
onAddFriend();
}}
placeholder={"Add friend"}
disableUnderline={true}
/>
</TableCell>
<TableCell align="left">{newFriend.lastSeen ? newFriend.lastSeen : ''}</TableCell>
<TableCell align="left">{newFriend.contactIn ? newFriend.contactIn : ''}</TableCell>
<TableCell align="left" className={classes.externalLinks}/>
</TableRow>
)
};
从“React”导入React;
从“@material ui/core/Input”导入输入;
从“lodash”导入{debounce};
...
const SampleRow=()=>{
let[newFriend,setNewFriend]=React.useState({name:'',lastSeen:'',contactIn:''});
const onAddFriend=debounce(()=>{
if(newFriend.name.length==0){
返回;
}
console.log(newFriend.name);
}, 2000);
返回(
{
setNewFriend({…newFriend,名称:event.target.value});
onAddFriend();
}}
占位符={“添加朋友”}
disableUnderline={true}
/>
{newFriend.lastSeen?newFriend.lastSeen:'}
{newFriend.contactIn?newFriend.contactIn:'}
)
};
发生的情况是,console.log
打印出每个更改(在超时2秒之后),并且不会取消以前的触发器
问题是为什么会这样?如何解决这个问题
我在复杂的useDebounce
逻辑或类组件中发现了类似的问题。没有找到此问题的参考
再见,尝试取消prevoius触发器:
import React from 'react';
import Input from "@material-ui/core/Input";
import {debounce} from "lodash";
...
const SampleRow = () => {
let [newFriend, setNewFriend] = React.useState({name: '', lastSeen: '', contactIn:
''});
const onAddFriend = debounce((abort) => {
if(abort){
return;
}
console.log(newFriend.name);
}, 2000);
return (
<TableRow>
<TableCell component="th" scope="row">
<Input
value={newFriend.name}
onChange={(event) => {
setNewFriend({...newFriend, name: event.target.value});
let abort = false;
if(event.target.value.length === 0){
abort = true;
}
onAddFriend(abort);
}}
placeholder={"Add friend"}
disableUnderline={true}
/>
</TableCell>
<TableCell align="left">{newFriend.lastSeen ? newFriend.lastSeen : ''}</TableCell>
<TableCell align="left">{newFriend.contactIn ? newFriend.contactIn : ''}</TableCell>
<TableCell align="left" className={classes.externalLinks}/>
</TableRow>
)
};
从“React”导入React;
从“@material ui/core/Input”导入输入;
从“lodash”导入{debounce};
...
const SampleRow=()=>{
let[newFriend,setNewFriend]=React.useState({name:'',lastSeen:'',contactIn:
''});
const onAddFriend=debounce((中止)=>{
如果(中止){
返回;
}
console.log(newFriend.name);
}, 2000);
返回(
{
setNewFriend({…newFriend,名称:event.target.value});
让中止=假;
if(event.target.value.length==0){
中止=真;
}
onAddFriend(中止);
}}
占位符={“添加朋友”}
disableUnderline={true}
/>
{newFriend.lastSeen?newFriend.lastSeen:'}
{newFriend.contactIn?newFriend.contactIn:'}
)
};
试试这个。它将始终检查队列中现有的取消公告,并取消它找到的任何取消公告。
请参阅:这里的问题是在每次渲染时都会重新创建取消公告功能 解决此问题的一种方法是将其移出功能组件。另一种方法是将组件更改为类组件,并将取消绑定的函数另存为属性
const{useState}=React
常数{debounce}=\u0;
const onAddFriend=debounce(console.log,2000);
常量应用=()=>{
const[newFriend,setNewFriend]=useState({name:'',lastSeen:'',contactIn:''});
常量handleInput=(事件)=>{
setNewFriend({…newFriend,名称:event.target.value});
onAddFriend(event.target.value);
}
返回(
更新{newFriend.name}
)
}
ReactDOM.render(,
document.getElementById(“根”)
它不起作用。最后一个触发器已取消,但其余触发器仍处于活动状态(并在给定的持续时间后打印到控制台)。我将在一段时间内更新我的答案。不幸的是,它不起作用。我确实理解了它背后的想法,但我的猜测是,onAddFriend
函数的重新渲染会导致它丢失标志。您必须清除已调用的去盎司函数。这不是去盎司的全部概念吗?调用函数应重置时间间隔
。我认为函数的呈现可能会导致问题。我试图event.persist()
,但没有成功。这正是您找到的解决方案“复杂”的原因。使用钩子,您需要使用useRef
来存储/处理/引用回调。这就是像UsedBouncedCallback这样的现有钩子处理它的方式。有一个很棒的关于useRef
的功能,如useInterval。我后来认为重新创建该函数可能会导致问题,但没有想到将其导出为外部函数以解决问题-很好,很简单,并按预期工作-谢谢!