简体   繁体   English

React useState 不更新异步函数中的值

[英]React useState not updating value in async function

const Login = () => {
  const [data, setData] = useState({
    name: "",
    email: "",
    password: ""
  });
  const [isLoading, setIsLoading] = useState(false);
  const [error, setError] = useState(""); // set empty error state

  const handleChange = event =>
    setData({ ...data, [event.target.name]: event.target.value });

  const handleSubmit = async event => { // async function to handle submit
    event.preventDefault();

    try {
      setIsLoading(true);

      const response = await axios.post( // response from server
        "http://localhost:5000/api/users/signup",
        JSON.stringify(data),
        {
          headers: {
            "Content-Type": "application/json"
          }
        }
      );
      console.log(response.data); // data comes back fine
      setIsLoading(false);
    } catch (err) {
      const message = err.response.data.message;
      setError(message); // set error message if there is an error
      setIsLoading(false); // always successfully setLoading to false
      console.log(isLoading); // result is false
      console.log(message); // result message
      console.log(error); // result is still empty string. state never updated with message
    }
  };

I cant seem to figure out why the error state is not updating in the catch block.我似乎无法弄清楚为什么错误状态没有在 catch 块中更新。 I alwasy receive a message and can log the message but the state never updates to the message.我总是收到消息并且可以记录消息,但状态永远不会更新到消息。 I noticed if I submit the form multiple times on the second submit the state will update.我注意到如果我在第二次提交时多次提交表单,状态会更新。

Any help is appreciated.任何帮助表示赞赏。

For any side-effect , like network call, data update which is async in nature.对于任何副作用,如网络调用,数据更新本质上是异步的。 You have to use useEffect .你必须使用useEffect This will solve the issue.这将解决问题。 To reuse the logic, You can create custom hooks .要重用逻辑,您可以创建自定义钩子 See the example: Custom-Hooks查看示例:自定义钩子

Use Effect:使用效果:

useEffect(
  () => {
    const subscription = props.source.subscribe();
    return () => {
      subscription.unsubscribe();
    };
  },
  [props.source],
);

Custom Hook:自定义挂钩:

function FriendStatus(props) {
  const [isOnline, setIsOnline] = useState(null);

  useEffect(() => {
    function handleStatusChange(status) {
      setIsOnline(status.isOnline);
    }

    ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
    return () => {
      ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
    };
  });

  if (isOnline === null) {
    return 'Loading...';
  }
  return isOnline ? 'Online' : 'Offline';
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM