这是我的代码,
const [state, setState] = useState({
email: '',
password: '',
last_name: '',
first_name: ''
});
const emailChangeHandler = (e) => {
setState(c => {
return {
...c,
email: e.target.value
}
})
}
return (
<form>
<input className="input" type="text" name="email" onChange={emailChangeHandler}/>
<input className="input" type="text"/>
<input className="input" type="text"/>
</form>
)
我正在尝试在输入值更改时更新状态。
但是错误"TypeError:无法读取null的属性'value'",
13 | setState(c => {
14 | return {
15 | ...c,
> 16 | email: e.target.value
17 | ^ }
18 | })
19 | }
所以,我试图在没有当前状态的情况下更新状态,比如:
const emailChangeHandler = (e) => {
setState({...state, email: e.target.value})
}
以及它的作用,但为什么?带currentstate的setstate和不带currentstate有什么区别?
如果使用setState回调,则事件值会在回调之前通过react清除。因此,在使用之前需要存储这些值
const email = e.target.value;
setState(c => {
return {
...c,
email,
}
})
就回调和不使用callbcak之间的区别而言,状态更新是批处理的,因此您使用函数setState,即带有回调的setState,即使在同一事件处理程序中进行了多个setState调用,也保证这些值将来自以前的更新
例如
const emailChangeHandler = (e) => {
setState({
...c,
email: [...c.email,e.target.value]
})
setState({
...c,
email: [...c.email, 'psw']
})
}
在上述情况下,如果c
是{email: ['xyz@g.com'], name: 'p'}
,则更新后的值将变为{email: ['xyz@g.com', 'psw'], name: 'p'}
,而不是{email: ['xyz@g.com', e.target.value, 'psw'], name: 'p'}
This will work:
const emailChangeHandler = (e) => {
const value = event.target.value;
setState(c => {
return {
...c,
email: value
}
})
}
因此,在这里,我们尝试在闭包中使用e.target.value
,闭包基本上会为后续的按键锁定event object
关于React事件:
React事件是复制本地dom事件的特殊合成事件
React基本上重新使用这些事件对象,在我们的情况下,它也会重复使用以前的事件对象,因此我们面临这个问题。