Javascript 表现出异常行为的文档侦听器

Javascript 表现出异常行为的文档侦听器,javascript,html,reactjs,Javascript,Html,Reactjs,我有一个带有onClick函数的按钮,它增加一个状态变量。我试图添加一个事件监听器,当用户按下enter键时,它会遵循完全相同的行为。但是,可以观察到,当用户按下enter键时,它似乎多次调用该函数,而不是仅调用一次。我怎样才能解决这个问题 const{useState,useffect}=React; /*导出默认值*/函数App(){ const[value,updateValue]=useState(0); useffect(()=>{ 文件。添加了文本列表(“按键”,e=>handl

我有一个带有onClick函数的按钮,它增加一个状态变量。我试图添加一个事件监听器,当用户按下enter键时,它会遵循完全相同的行为。但是,可以观察到,当用户按下enter键时,它似乎多次调用该函数,而不是仅调用一次。我怎样才能解决这个问题

const{useState,useffect}=React;
/*导出默认值*/函数App(){
const[value,updateValue]=useState(0);
useffect(()=>{
文件。添加了文本列表(“按键”,e=>handleKeyPress(e));
}, []);
const onSubmit=()=>{
console.log(值);
updateValue(oldVal=>(oldVal+1)%2);
};
const handleKeyPress=e=>{
如果(e.key==“输入”){
onSubmit();
}
};
返回onSubmit()}>单击我;
}
render(,document.getElementById(“根”))

问题是您的
useffect
只会看到
handleKeyPress
第一个版本,它只会看到
onSubmit
第一个版本,它只会看到
值的第一个版本。相比之下,您的按钮的单击处理程序附加了当前版本的
onSubmit
,因此它看到的是
value
的当前值,而不是过时的值

由于
onSubmit
使用状态信息(
value
),并且
handleKeyPress
使用
onSubmit
,一种解决方案是将
handleKeyPress
作为依赖项添加到
useffect
代码中,并使用清理回调来更新正在使用的
handleKeyPress

useEffect(() => {
  document.addEventListener("keypress", handleKeyPress); // No need for the arrow function here, and...
  return () => {
      document.removeEventListener("keypress", handleKeyPress); // ...not using one simplifies this
  };
}, [handleKeyPress]);
您还需要将其移动到创建函数的下方:

const{useState,useffect}=React;
/*导出默认值*/函数App(){
const[value,updateValue]=useState(0);
const onSubmit=()=>{
console.log(值);
updateValue(oldVal=>(oldVal+1)%2);
};
const handleKeyPress=e=>{
如果(e.key==“输入”){
onSubmit();
}
};
useffect(()=>{
document.addEventListener(“keypress”,handleKeyPress);//这里不需要箭头函数,并且。。。
return()=>{
document.removeEventListener(“keypress”,handleKeyPress);/…不使用它可以简化这一过程
};
},[handleKeyPress]);
返回onSubmit()}>单击我;
}
render(,document.getElementById(“根”))


在这种情况下,仅从代码提供的内容就可以很清楚地看出问题所在(很好!),但通常情况下,如果您可以在此处使用堆栈片段(
[]
工具栏按钮)在现场运行,这比非现场链接要好。如果你使用非现场链接,你很容易遗漏一些必要的东西,让你的问题清晰完整。堆栈代码段支持React,包括JSX。我已经为你做了上述工作。我还更新了我的答案,以显示两种方法来解决我可以观察到的问题。我从来没有在代码段中看到“多次”行为,只看到过时的数据。我认为将空数组传递给usEffect意味着它只被调用一次。如果不是这样,传递空数组做什么?另外,当我按Enter键调用函数时,值不再被更新。只有当我点击按钮时,值才会更新。@complezzityy-你说得很对,我记错了
[]
而不是没有提供一个。(我真的应该能够把他们弄清楚!)我已经确定了答案,但也可能不是答案,这取决于你的具体情况。因此,如果您可以在现场进行MCVE,这将有助于人们回答您的问题。@complexityy-还有一个问题是,
useffect
只使用了第一个版本的
handleKeyPress