反应的on change输入延迟

发布于 2025-02-03 03:12:40 字数 730 浏览 5 评论 0原文

我以前从未真正注意到过。不确定我的代码中是否有错误,或者Onchange始终以这种方式行为,但是我会得到输入延迟,并且不确定如何解决。这是我的意思的一个例子:

​即使已正确输入用户名和密码,它也可以接收正确的状态。

我的代码相当简单:

const [state, setState] = useState<LoginStateType>(iLoginState)
const {username, password} = state

const handleChange = (event: ChangeEventType) => {
    const {name, value} = event.target
    setState({...state, [name]: value})
    console.log(username)
}

{...}

<input type="text" name="username" value={username} onChange={handleChange}/>
<input type="text" name="password" value={password} onChange={handleChange}/>

任何帮助都将不胜感激,谢谢!

I've never really noticed this before; not sure if theres a bug in my code or if onChange always behaves this way, but I'm getting an input delay and am not sure how to resolve it. Heres an example of what I mean:

enter image description here

As you can see the console only prints the previous state which is a nuisance because that means to have the user log in they have to click the "Go" button twice for it to receive the correct state, even if the username and password has been correctly input.

My code is fairly straight forward:

const [state, setState] = useState<LoginStateType>(iLoginState)
const {username, password} = state

const handleChange = (event: ChangeEventType) => {
    const {name, value} = event.target
    setState({...state, [name]: value})
    console.log(username)
}

{...}

<input type="text" name="username" value={username} onChange={handleChange}/>
<input type="text" name="password" value={password} onChange={handleChange}/>

Any help is appreciated, thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

不气馁 2025-02-10 03:12:40

因为状态更新可能是异步的


使用钩子,这可以通过

const [state, setState] = useState(/* ... */)

setState(/* ... */)

useEffect(() => {
  // state is guaranteed to be what you want
}, [state])

Since State Updates May Be Asynchronous.


With hooks, this can be achieved by

const [state, setState] = useState(/* ... */)

setState(/* ... */)

useEffect(() => {
  // state is guaranteed to be what you want
}, [state])
原野 2025-02-10 03:12:40

SetState是一个异步步骤,不要立即获得新值!

setState is a async step, not get new value immediately!

百思不得你姐 2025-02-10 03:12:40

我最终做的可能有点麻烦,但完成了工作。除了国家(我已经设置的用户室内文本所必需的)之外,我还设置了两个Useref常数:

const inputUserName = useRef<HTMLInputElement | null>(null)
const inputPassword = useRef<HTMLInputElement | null>(null)

{...}

<input type="text" name="username" ref={inputUserName} value={username} onChange={handleChange}/>
<input type={inputType as string} ref={inputPassword} name="password" value={password} onChange={handleChange}/>

因此,我拥有的完整代码如下:

  //-------------ADMIN STATE-------------
  const [state, setState] = useState<LoginStateType>(iLoginState)
  const {username, password} = state

  //-------------USE EFFECT-------------
    //UseEffect: this is called when the context is set, I think
  useEffect(() => {
    //dispatch must be called before submit, I think because its an asynchronous call
    dispatch(getAdminsRedux());
        setContext(localStorage.getItem('user'))
        if (context !== null){
          navigate("/admin", {replace: true})
        }

  }, [setContext, context, dispatch, navigate]);

  //-------------HANDLE CHANGE-------------
  const handleChange = (event: ChangeEventType) => {
    const {name, value} = event.target
    setState({...state, [name]: value})
  }

  //-------------HANDLE LOGIN-------------
  const handleLogin = async (event: MouseEvent) => {
    event.preventDefault()

    admins.forEach(async (admin)  => {
      if(admin.username === inputUserName.current!.value){
        const comparedHash = compareHash(inputPassword.current!.value, admin.password)
        if (comparedHash){
          setContext(state.username)
          localStorage.setItem('user', state.username)
        }
      }
    });
  }

What I ended up doing was perhaps a bit cumbersome but it gets the job done. Aside from the state (which is necessary for the useContext I have set up) I also set up two useRef constants:

const inputUserName = useRef<HTMLInputElement | null>(null)
const inputPassword = useRef<HTMLInputElement | null>(null)

{...}

<input type="text" name="username" ref={inputUserName} value={username} onChange={handleChange}/>
<input type={inputType as string} ref={inputPassword} name="password" value={password} onChange={handleChange}/>

So the full code I have is as follows:

  //-------------ADMIN STATE-------------
  const [state, setState] = useState<LoginStateType>(iLoginState)
  const {username, password} = state

  //-------------USE EFFECT-------------
    //UseEffect: this is called when the context is set, I think
  useEffect(() => {
    //dispatch must be called before submit, I think because its an asynchronous call
    dispatch(getAdminsRedux());
        setContext(localStorage.getItem('user'))
        if (context !== null){
          navigate("/admin", {replace: true})
        }

  }, [setContext, context, dispatch, navigate]);

  //-------------HANDLE CHANGE-------------
  const handleChange = (event: ChangeEventType) => {
    const {name, value} = event.target
    setState({...state, [name]: value})
  }

  //-------------HANDLE LOGIN-------------
  const handleLogin = async (event: MouseEvent) => {
    event.preventDefault()

    admins.forEach(async (admin)  => {
      if(admin.username === inputUserName.current!.value){
        const comparedHash = compareHash(inputPassword.current!.value, admin.password)
        if (comparedHash){
          setContext(state.username)
          localStorage.setItem('user', state.username)
        }
      }
    });
  }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文