React 中的 onChange 输入延迟

onChange input delay in React

我以前从来没有真正注意到这一点;不确定我的代码中是否存在错误或者 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}/>

感谢任何帮助,谢谢!

State Updates May Be Asynchronous.


有了钩子,这可以通过

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

setState(/* ... */)

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

setState 是一个异步步骤,不会立即获取新值!

我最后做的可能有点麻烦,但它完成了工作。除了状态(这是我设置的 useContext 所必需的)之外,我还设置了两个 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)
        }
      }
    });
  }