本文介绍了反应useState()不同步更新值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果在设置值之后立即调用,则useuse()函数不会更新变量的值.

React useState() doesn't update value of the variable if called just after setting value.

我阅读了有关useEffect()的文章,但实际上并不知道这对这种特殊情况有什么用.

I read about useEffect(), but don't really know how this will be useful for this particular scenario.

完整代码 (请打开控制台标签以查看变量状态)

Full code (please open the console tab to see the variable status)

// hook
const [ error, setError ] = useState<boolean>();
const handleSubmit = (e: any): void => {
    e.preventDefault();
    if (email.length < 4) {
      setError(true);
    }
    if (password.length < 5) {
      setError(true);
    }
    console.log(error); // <== still false even after setting it to true
    if (!error) {
      console.log("validation passed, creating token");
      setToken();
    } else {
      console.log("errors");
    }
  };

推荐答案

让我们假设用户没有有效的凭据.问题在这里:

Let's assume the user does not have valid credentials. The problem is here:

if (email.length < 4) {  // <== this gets executed
  setError(true);
}
if (password.length < 5) { // <== this gets executed
  setError(true);
}
console.log(error); // <== still false even after setting it to true
if (!error) { // <== this check runs before setError(true) is complete. error is still false.
  console.log("validation passed, creating token");
  setToken();
} else {
  console.log("errors");
}

您正在使用全部独立运行的多个if-check,而不是使用单个if-check.您的代码将执行所有if检查.在一项检查中,如果满足以下条件之一,则调用setError(true),但是setError()是异步的.该操作在调用下一个if-check之前没有完成,这就是为什么它使您看上去从未保存过您的值的原因.

You are using multiple if-checks that all run independently, instead of using a single one. Your code executes all if-checks. In one check, you call setError(true) when one of the conditions is passed, but setError() is asynchronous. The action does not complete before the next if-check is called, which is why it gives the appearance that your value was never saved.

您可以结合使用if-else和useEffect来更简洁地做到这一点: https://codesandbox.io/s/dazzling-pascal-78gqp

You can do this more cleanly with a combination of if-else and useEffect instead: https://codesandbox.io/s/dazzling-pascal-78gqp

import * as React from "react";

const Login: React.FC = (props: any) => {
  const [email, setEmail] = React.useState("");
  const [password, setPassword] = React.useState("");
  const [error, setError] = React.useState(null);

  const handleEmailChange = (e: any): void => {
    const { value } = e.target;
    setEmail(value);
  };

  const handlePasswordChange = (e: any): void => {
    const { value } = e.target;
    setPassword(value);
  };

  const handleSubmit = (e: any): void => {
    e.preventDefault();
    if (email.length < 4 || password.length < 5) {
      setError(true);
    } else {
      setError(false);
    }
  };

  const setToken = () => {
    //token logic goes here
    console.log("setting token");
  };

  React.useEffect(() => {
    if (error === false) {
      setToken();
    }
  }, [error]); // <== will run when error value is changed.

  return (
    <div>
      <form onSubmit={handleSubmit}>
        <input
          type="text"
          placeholder="[email protected]"
          onChange={handleEmailChange}
        />
        <br />
        <input
          type="password"
          placeholder="password"
          onChange={handlePasswordChange}
        />
        <br />
        <input type="submit" value="submit" />
      </form>

      {error ? <h1>error true</h1> : <h1>error false</h1>}
    </div>
  );
};

export default Login;

这篇关于反应useState()不同步更新值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-18 11:02