Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
416 views
in Technique[技术] by (71.8m points)

javascript - Fetching data and updating the isLoading but setState isn't updating correctly and it always ends up being the initial isLoading state

const App = () => {
    const [user, setUser] = useState({
        name: "",
        organisationName: "",
        id: "",
        isLoading: false,
    });
    useEffect(() => {
        const userId = getUserIdFromParams();
        if (userId) {
            setUser({...user, isLoading: true}); // dispatch(STARTED_FETCHING_LEAD)
            (async () => {
                const retrievedUser = await getLeadFromDatabase(leadId);
                if (retrievedUser) setUser({...user, ...retrievedUser});
            })();
        }
        setUser({...user, isLoading: false});
    }, []);

What I expect to happen is the following:

if there is userId in the URL parameters, isLoading is set to true (component updates accordingly). Then when a user is retrieved, the state will be set to the user details and then finally the state is updated one last time to isLoading false.

What happens:

State doesn't update accordingly and it always ends up being the same state as the one set in useState. So if I set isLoading: true in the original state. The loading component will be shown indefinitely, when I set to false it ends up being false.

Anyone has any idea what's going on here? All help is much appreciated :)

question from:https://stackoverflow.com/questions/65643759/fetching-data-and-updating-the-isloading-but-setstate-isnt-updating-correctly-a

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)
  1. You don't need to write setUser({...user, isLoading: true}) you can just say setUser({ isLoading: true }) see the docs

  2. You retrieve the user asynchronously but reset isLoading to true synchronously. So isLoading will most likely be false before the user is loaded. I would rewrite it like this:

useEffect(() => {
    const userId = getUserIdFromParams();
    if (userId) {
        setUser({...user, isLoading: true}); // dispatch(STARTED_FETCHING_LEAD)
        (async () => {
            const retrievedUser = await getLeadFromDatabase(leadId);
            if (retrievedUser) setUser({...retrievedUser, isLoading: false});
        })();
    }
}, []);

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...