Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/442.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 在useState'中丢失合成事件;s函数用于更新状态_Javascript_Reactjs - Fatal编程技术网

Javascript 在useState'中丢失合成事件;s函数用于更新状态

Javascript 在useState'中丢失合成事件;s函数用于更新状态,javascript,reactjs,Javascript,Reactjs,我将useState钩子用于功能组件,其中我面临一种奇怪的行为。 我是这样使用useState的 const [state, setState] = useState({ title: "", amount: '' }); 与表单数据绑定的状态相同。如果我过去喜欢这个 <input type="text" id="title" value={state.title} onChange={event => setState( { ...state, title: event.

我将useState钩子用于功能组件,其中我面临一种奇怪的行为。 我是这样使用useState的

const [state, setState] = useState({ title: "", amount: '' });
与表单数据绑定的状态相同。如果我过去喜欢这个

<input type="text" id="title" value={state.title}
    onChange={event => setState( { ...state, title: event.target.value })} />
<input type="text" id="title" value={state.title}
    onChange={event => setState((prevState) => {
            return {
              ...prevState,
              title: event.target.value
            }
          })
          } />
setState({…state,title:event.target.value})}/>
然后它工作得很好,但是如果我使用前面的状态作为实时状态,就像这样

<input type="text" id="title" value={state.title}
    onChange={event => setState( { ...state, title: event.target.value })} />
<input type="text" id="title" value={state.title}
    onChange={event => setState((prevState) => {
            return {
              ...prevState,
              title: event.target.value
            }
          })
          } />
setState((prevState)=>{
返回{
…国家,
标题:event.target.value
}
})
} />
然后,事件在第二次按键时松开。在研究中,我发现这是由于事件池,我可以使用event.persist()实现这一点。
我的问题是,为什么它在我解释的第一个场景中有效,为什么不在第二个场景中有效?

因为在第二次迭代中,事件参数未定义。所以它找不到抛出null异常的值。您可以通过传递一个箭头函数来简单地克服这种情况

//获取一个钩子函数
const{useState}=React;
常量示例=({title})=>{
const[count,setCount]=useState(0);
const[state,setState]=useState({title:,amount:''});
常量设置值=(值)=>{
设置状态((prevState)=>{
console.log(prevState);
返回{
…国家,
标题:value/(event.target?event.target.value:'val')
}
})
}
返回(
setState({…状态,标题:event.target.value})}/>
setValue(event.target.value)}
/>
);
};
//渲染它
ReactDOM.render(
,
document.getElementById(“react”)
);

因此,在
设置状态({…状态,title:event.target.value})
中,您正在传播状态,这意味着保持当前状态,并将状态对象的
标题更改为
输入中的当前值。在

setState((prevState) => {
        return {
          ...prevState,
          title: event.target.value
        }
      })
使用事件池,因此
prevState
是作为回调发送的事件数据(在本例中为状态对象),因此,当您输入第一个字符时,事件对象实际上被发送回池中,当您输入第二个字符时,事件对象将已返回到池中,因此事件将为
null
。因此,为了克服这个问题,您可以使用
event.persist()
使事件持久化,这将允许您以异步方式使用事件属性,希望这对您有所帮助

 <input
    type='text'
    id='title'
    value={state.title}
    onChange={event => {
      event.persist();
      setState(prevState => {
        return {
          ...prevState,
          title: event.target.value
        };
      });
    }}
  />
{
event.persist();
设置状态(prevState=>{
返回{
…国家,
标题:event.target.value
};
});
}}
/>

在第一个示例中,您直接在事件处理程序中读取事件数据,而事件仍然是当前的。但是,在第二个示例中,您正在传递给
setState()
的回调中读取它。当事件处理程序已返回且本机事件(由React的SyntheticEvent包装)已取消引用的状态已更新时(这是整个回调的要点),将异步调用此回调。这是您通过调用
event.persist()

来阻止的,这里实际发生的事情是由于关闭以及React处理事件的方式造成的。 setState下的函数是closure函数,因此事件的值在第一次执行时被锁定,closure尝试获取第一个值(锁定值)。React实现,其中,事件对象在调用事件回调后将为空

但是React还提供了使用persist方法从事件池中拉出事件的方法,如下所示

   `onChange={event => {
  event.persist();
  setState(prevSt....` 
这样,React将永远不会使对象无效,因此closure将始终具有访问事件方法的权限