Reputation: 8589
I have the following code for a "protected route" in React:
import React, { useState, useEffect, useContext } from 'react';
import LoadingPageContext from '../../contexts/LoadingPageContext';
import PropTypes from 'prop-types';
import { Redirect } from 'react-router-dom';
import authorizeWorker from '../../workers/authorize-worker';
/**
* A protected route that calls the authorize API and redirects to login
* on fail
* @param {Element} component The component to redirect to on success
* @param {String} path The route to redirect to after login
*/
const ProtectedRoute = ({ component, path }) => {
const [isAuthenticated, setIsAuthenticated] = useState(null);
const { loadingBarRef } = useContext(LoadingPageContext);
const Component = component;
console.log('Protected route rendered');
useEffect(() => {
console.log('protected route use effect')
loadingBarRef.current.continuousStart();
authorizeWorker()
.then(() => setIsAuthenticated(true))
.catch(() => setIsAuthenticated(false))
.finally(() => loadingBarRef.current.complete());
}, []);
if (isAuthenticated === true) {
return <Component />;
}
if (isAuthenticated === false) {
return <Redirect
to={{ pathname:'/login', state: { redirectPath: path }}}
/>;
}
return null;
}
ProtectedRoute.propTypes = {
component: PropTypes.func.isRequired,
path: PropTypes.string
};
export default ProtectedRoute;
The router appears to be working ok and I see the correct pages/UI on the screen when I click on a new route. However useEffect
does not seem to be called each time I route. I have confirmed this using console.log
. The component does indeed render each time because Protected route rendered
is printed to screen but protected route use effect
isn't. Any idea what I am doing wrong here? For reference my router looks like this:
const DashboardSwitch = () => {
const { path } = useRouteMatch();
return (
<Switch>
<ProtectedRoute exact path={`${path}`} component={Home} />
<ProtectedRoute exact path={`${path}/home`} component={Home} />
<ProtectedRoute exact path={`${path}/bonus`} component={Bonuses} />
<ProtectedRoute exact path={`${path}/newpage`} component={NewPage} />
<ProtectedRoute exact path={`${path}/account`} component={Account} />
<Route exact path={`${path}/mypages`} component={MyPages} />
<Route path="*"><NotFound /></Route>
</Switch>
);
}
Amy help on this would be great. Thanks!
Upvotes: 0
Views: 782
Reputation: 367
useEffect is the equivalent of componentDidMount and componentDidUpdate in class components. When you pass an empty array - [] - it will only act as componentDidMount - meaning only once. If you want the effect to be called each time a new route is presented, you should pass that as a prop:
useEffect(() => {
console.log('protected route use effect')
loadingBarRef.current.continuousStart();
authorizeWorker()
.then(() => setIsAuthenticated(true))
.catch(() => setIsAuthenticated(false))
.finally(() => loadingBarRef.current.complete());
}, [path]);
Upvotes: 1