我正在为电子邮件创建输入表单,并且在onChange上存在延迟,以致无法多次调用api。
这是我的代码:
const InformationCollection = (props) => {
const [email, setEmail] = useState()
const [collectedEmail, setCollectedEmail] = useState(1)
useEffect(() => {
let timeout = setTimeout(() => {
setCollectedEmail(email)
console.log(collectedEmail)
}, 500)
return () => {
clearTimeout(timeout)
}
}, [email])
return (
<div className="form-group">
<label htmlFor="inputmail">Email address</label>
<input
type="email"
className="form-control"
onChange={(e) => {
setEmail(e.target.value)
console.log(e.target.value + "this is what is set" + email)
}}
aria-label="Enter e-mail address"
/>
</div>
)
}
export default InformationCollection
在这一行上,如果我输入“ 1” console.log(e.target.value + "this is what is set" + email)
,则e.target.value为1,但email
未定义。
在下一个字符“ 12”上,e.target.value为12但email
为1
任何人都可以帮忙吗?
更新:
解决方案是使用2个useEffectHooks。一个用于格式为email
的值,另一个用于延迟值collectedEmail
第二种解决方法是在第一个useEffect挂钩内进行抓取
const InformationCollection = (props) => {
const [email, setEmail] = useState()
const [collectedEmail, setCollectedEmail] = useState()
useEffect(() => {
let timeout = setTimeout(() => {
//fetch directly here
setCollectedEmail(email)
console.log(collectedEmail)
}, 500)
return () => {
clearTimeout(timeout)
}
}, [email])
useEffect(() => {
//fetch() here
console.log(collectedEmail) //right value
}, [collectedEmail])
return (
<div className="form-group">
<label htmlFor="inputmail">Email address</label>
<input
type="email"
className="form-control"
onChange={(e) => {
setEmail(e.target.value)
console.log(e.target.value + "this is what is set" + email)
}}
aria-label="Enter e-mail address"
/>
</div>
)
}
export default InformationCollection
答案 0 :(得分:2)
这不是预期的行为吗? email
始终是onChange
处理程序内部进行更改之前的值。因为还没有发生重新渲染。
要查看呈现的值,请执行以下操作:
return (
<div className="form-group">
<label htmlFor="inputmail">Email address: { email }</label>
<input
type="email"
className="form-control"
onChange={(e) => {
setEmail(e.target.value)
console.log(e.target.value + "this is what is set" + email)
}}
aria-label="Enter e-mail address"
/>
</div>
)
答案 1 :(得分:2)
状态是异步更新的,这就是为什么在更新状态后第一次尝试记录email
时未定义它的原因。
您可以将电子邮件记录在useEffect
挂钩中,该电子邮件在更改后将被调用。
在下一个字符“ 12”上,e.target.value为12,电子邮件为1
email
是1
,因为第一次触发onChange
事件时,email
是未定义的,而第二次触发onChange
事件时,{ {1}}已异步更新为email