axios.get function in ComponentDidMount not setting state as expected

时光毁灭记忆、已成空白 提交于 2021-01-29 13:29:43

问题


In my header component, I have conditional rendering set to display different links depending on if the user is logged in or not. The conditional rendering works fine EXCEPT the fact that it blinks one set of links before displaying the proper set of links.

It dawned on me this is because of the axios.get call I have that retrieves the user's status. The state variable is initially set to false. If the user is logged in, the get call will indicate that and the state variable will get set to true. The short delay makes it so the "not logged in" links are shown momentarily before the "is logged in" links get displayed.

I've tried quite a few recommended approaches in both componentDidMount and componentWillMount - nothing seems to be working:

componentDidMount() {
    axios.get('http://localhost:8000/api/login', {
        withCredentials: true
    }).then(res => {
        if (res.data.loggedIn) {
            this.setState({isLogged: true});
        } else {
            this.setState({isLogged: false});
        }
    }).catch(error => {
        this.setState({isLogged: false});
    });
}

Next approach:

async componentDidMount() {
    const res = await axios.get('http://localhost:8000/api/login', {
        withCredentials: true
    });
    const logged = await res.data.loggedIn;

    if (logged) {
        this.setState({isLogged: true});
    } else {
        this.setState({isLogged: false});
    }
}

I've tried call back functions with the same results.

The conditional rendering is the typical:

{this.state.isLogged && <LoggedIn />}

I'm clearly failing to see something basic in how the async functions work - I'm just not sure what that is!

Thanks in advance!!


回答1:


Here’s a method I’ve found useful. Add a loading variable to state:

async componentDidMount() {
    this.setState({ loading: true });

    const res = await axios.get('http://localhost:8000/api/login', {
        withCredentials: true
    });
    const logged = await res.data.loggedIn;

    if (logged) {
        this.setState({isLogged: true, loading: false });
    } else {
        this.setState({isLogged: false, loading: false });
    }
}

Then, you can add:

{!this.state.loading && this.state.isLogged && ...}

You can always set loading to true in your component’s constructor, if you still see a flash, but I would try to keep loading in the same method as the process that’s actually loading.




回答2:


The best that you can do in this case is to show nothing or a spinner until the request has finished. It doesn't matter what you do (async/await, promise, callback) that request is going to take some time.



来源:https://stackoverflow.com/questions/50920311/axios-get-function-in-componentdidmount-not-setting-state-as-expected

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!