问题
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