useState 不更新它的值

useState doesn't update its value

我正在为电子邮件创建一个输入表单,我有一个延迟的 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

这不是预期的行为吗? 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>
    )

state 是异步更新的,这就是为什么 email 在更新状态后尝试记录它时第一次未定义的原因。

您可以在 useEffect 挂钩中记录电子邮件,该挂钩将在电子邮件更改后调用。

On the next character "12", e.target.value is 12 but email is 1

email1 因为当 onChange 事件第一次触发时,email 是未定义的,但是当 onChange 事件第二次触发时, email 已经异步更新为 1