Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/449.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript React.js中功能组件内部的去抖动_Javascript_Reactjs_React Hooks_Lodash_Debounce - Fatal编程技术网

Javascript React.js中功能组件内部的去抖动

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

尝试在具有随更改而更新的输入字段的react组件上创建延迟

代码如下:

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。我后来认为重新创建该函数可能会导致问题,但没有想到将其导出为外部函数以解决问题-很好,很简单,并按预期工作-谢谢!