首页 > 解决方案 > 如何更新 useState 并等待它完成,程序无限运行

问题描述

我正在尝试使用 useState 来更新会话存储中的变量,然后我想向我的服务器发送一个 api 请求并获取一些数据。如果我将电子邮件和密码硬编码到 api 请求中,这一切都有效。但是,当我等待程序获取数据时,api 请求在异步 useState 函数完成之前正在运行。我尝试使用 useEffect 并等待用户更改,以便函数在获取数据之前不会运行,但这会让我陷入无限循环。

这是获取登录数据并进行身份验证的更广泛程序的一部分。在这一步之后,我希望能够移动到一个新页面,然后从我的服务器加载一些数据,但这就是它正在破坏的地方。

import axios from 'axios';
import Navbar from './Navbar';
import { UserContext } from './UserContext';
import React, { useContext, useState, useEffect } from 'react'
function Watchlist() {

    const [user , setUser] = useState(); 

    const [watchlist, setWatchlist] = useState();

    setUser({
        name: sessionStorage.getItem('sessionName'),
        email: sessionStorage.getItem('sessionEmail'),
        passowrd: sessionStorage.getItem('sessionPassword'),
        authenticated: sessionStorage.getItem('sessionAuthenticated')
    })
    useEffect(() => {
        getWatchlist()
    }, [user])


    function getWatchlist() {

        console.log(`axios.post ${user.email} ${user.password}`);
        axios.post(`/api/users/watchlist/id/${user.email}/${user.password}`).then((res) => {
            if (res) {
                setWatchlist(res.data);
                console.log(JSON.stringify(res.data));
            }
        }).catch((err) => {
            console.log(err);
        })

    }





    return (
        <div>
            <Navbar />
            <div>{JSON.stringify(watchlist)}</div>
        </div>
    )
} export default Watchlist; 

标签: reactjsasynchronoususe-effectuse-state

解决方案


你永远不应该无条件地调用状态更新器。每次状态更新,组件都会重新渲染,所以无条件更新状态总是会产生无限循环。

只需将您的状态对象默认为您想要的对象。

const [user , setUser] = useState({
  name: sessionStorage.getItem('sessionName'),
  email: sessionStorage.getItem('sessionEmail'),
  passowrd: sessionStorage.getItem('sessionPassword'),
  authenticated: sessionStorage.getItem('sessionAuthenticated')
}); 


推荐阅读