I am trying to authenticate user on each route change with react-router-dom
and react hooks
.
The idea is that each time user navigates to a route the system makes an api call and authenticate the user.
I need to achieve this because I use react-redux
, and on each window reload the redux state is not persisted. So i need to set the isLoggedNow
prop to true
again:
const PrivateRoute = ({
ponent: Component,
checkOnEachRoute: checkReq,
isUserLogged,
...rest
}) => {
const [isLoggedNow, setLogged] = useState(isUserLogged);
useEffect(
() => {
const fetchStatus = async () => {
try {
await selectisUserLogged();
setLogged(true);
} catch (error) {
console.log(error);
}
};
fetchStatus();
},
[isUserLogged],
);
return (
<Route
{...rest}
render={props =>
isLoggedNow ? (
<div>
<Component {...props} />
</div>
) : (
<Redirect
to={{
pathname: '/login',
}}
/>
)
}
/>
);
};
I then would use the above PrivateRoute
like this:
function App(props) {
return (
<div>
<Switch location={props.location}>
<Route exact path="/login" ponent={Login} />
<PrivateRoute exact path="/sidebar" ponent={Sidebar} />
</Switch>
</div>
);
}
First the isUserLogged
is true
, but after window reload I get an error Warning: Can't perform a React state update on an unmounted ponent.
So how can I achieve this, so on each window reload I authenticate the user? I am looking for some kind of ponentWillMount
.
I am trying to authenticate user on each route change with react-router-dom
and react hooks
.
The idea is that each time user navigates to a route the system makes an api call and authenticate the user.
I need to achieve this because I use react-redux
, and on each window reload the redux state is not persisted. So i need to set the isLoggedNow
prop to true
again:
const PrivateRoute = ({
ponent: Component,
checkOnEachRoute: checkReq,
isUserLogged,
...rest
}) => {
const [isLoggedNow, setLogged] = useState(isUserLogged);
useEffect(
() => {
const fetchStatus = async () => {
try {
await selectisUserLogged();
setLogged(true);
} catch (error) {
console.log(error);
}
};
fetchStatus();
},
[isUserLogged],
);
return (
<Route
{...rest}
render={props =>
isLoggedNow ? (
<div>
<Component {...props} />
</div>
) : (
<Redirect
to={{
pathname: '/login',
}}
/>
)
}
/>
);
};
I then would use the above PrivateRoute
like this:
function App(props) {
return (
<div>
<Switch location={props.location}>
<Route exact path="/login" ponent={Login} />
<PrivateRoute exact path="/sidebar" ponent={Sidebar} />
</Switch>
</div>
);
}
First the isUserLogged
is true
, but after window reload I get an error Warning: Can't perform a React state update on an unmounted ponent.
So how can I achieve this, so on each window reload I authenticate the user? I am looking for some kind of ponentWillMount
.
- did you have a chance to resolve this issue? – genesst Commented May 14, 2019 at 11:47
- @camelCase yes! – user1665355 Commented May 14, 2019 at 11:47
- care to share? :) facing exact same issue at the moment – genesst Commented May 14, 2019 at 11:51
- @camelCase See my answer, does it solve it for you?:) – user1665355 Commented May 14, 2019 at 11:53
1 Answer
Reset to default 6Something like this works (where isUserLogged
is a prop from redux):
function PrivateRoute({ ponent: Component, isUserLogged, ...rest }) {
const [isLoading, setLoading] = useState(true);
const [isAuthenticated, setAuth] = useState(false);
useEffect(() => {
const fetchLogged = async () => {
try {
setLoading(true);
const url = new URL(fetchUrl);
const fetchedUrl = await fetchApi(url);
setAuth(fetchedUrl.body.isAllowed);
setLoading(false);
} catch (error) {
setLoading(false);
}
};
fetchLogged();
}, []);
return (
<Route
{...rest}
render={props =>
// eslint-disable-next-line no-nested-ternary
isUserLogged || isAuthenticated ? (
<Component {...props} />
) : isLoading ? (
<Spin size="large" />
) : (
<Redirect
to={{
pathname: '/login',
}}
/>
)
}
/>
);
}