I have a React component that is rendered when I visit the /service
path of my website. E.g. my-site.com/service
.
The problem is, this page should only be viewable if logged in, otherwise, get redirected to the login page. However, before redirecting, the component gets flashed to the screen for a split second.
How can I prevent my component from showing at all when not yet logged in?
This is how I have tried so far:
I am using a class component
.
In componentDidMount()
, if the getUsers
function returns an error (meaning not logged in), then set the redirect
variable to true
.
componentDidMount() {
UserService.getUsers().catch((err) => {
this.setState({ redirect: true });
});
}
And then I use that variable like this:
render() {
const { redirect } = this.state;
if (redirect) {
return <Navigate to="/login" />;
}
return (
<Fragment>
<div>This is my div</div>
<div>OTHER IMPORTANT DATA</div>
<Fragment>
);
}
So when not logged in, you can still my div
and OTHER IMPORTANT DATA
for a split second before you get redirected. How can I prevent this from happening?
This is my App.js
:
function App() {
return (
<Fragment>
<Router>
<HeaderComponent />
<Routes>
<Route path="/login" element={<Login />}></Route>
<Route path="/register" element={<Register />}></Route>
<Route path="/service" element={<MyComponent />}></Route>
<Route path="/" element={<LandingPage />}></Route>
</Routes>
<FooterComponent />
</Router>
</Fragment>
);
}
>Solution :
Add another state value indicating whether loading is finished or not. If its not loaded, render nothing (or a placeholder). If it is loaded, then do the same thing you’re doing now.
state = {
redirect: false,
loaded: false,
}
componentDidMount() {
UserService.getUsers()
.then(() => {
this.setState({ loaded: true });
}).catch((err) => {
this.setState({ loaded: true, redirect: true });
});
}
render() {
const { redirect, loaded } = this.state;
if (!loaded) {
return null;
}
if (redirect) {
return <Navigate to="/login" />;
}
return (
<Fragment>
<div>This is my div</div>
<div>OTHER IMPORTANT DATA</div>
<Fragment>
);
}