This is the main component of my Ionic4 app ("PrivateRoute" component is from react-router-private):
const App: React.FC = (props: any) => {
const { userLogged } = props.logged;
return (
<IonApp>
<IonReactRouter>
<IonRouterOutlet id="principal">
<Route exact path="/" render={() => <Redirect to="/login" />} />
<Route exact path="/login" component={LoginPage} />
<PrivateRoute exact path="/dashboard" component={Dashboard} authStatus={userLogged.isLogged} redirectURL="/login" />
</IonRouterOutlet>
</IonReactRouter>
/>
</IonApp>
);
}
const mapStateToProps = (state: any) => {
return {
logged: state.logged,
};
}
export default connect(mapStateToProps)(App);
and this is my LoginPage component:
const LoginPage: React.FC = (props: any) => {
const { userLogged } = props.logged;
const handleLogin = (inputs: any) => {
const user = {
"username": inputs.username,
"password": inputs.password,
};
axios.post(`URL`,
user,
)
.then(response => {
props.setLogged(response.data);
})
.catch(error => {});
}
return (
<>{userLogged.isLogged ?
<Redirect to="/dashboard" />
:
<IonPage>
<IonContent>
<>
<IonGrid>
<IonRow>
<IonCol
offsetXl="3" sizeXl="6"
offsetLg="2" sizeLg="8"
offsetMd="2" sizeMd="8"
offsetSm="1" sizeSm="10"
sizeXs="12">
<Login save={handleLogin} >
</Login>
</IonCol>
</IonRow>
</IonGrid>
</>
</IonContent>
</IonPage>
}
</>
);
};
const mapStateToProps = (state: any) => {
return {
logged: state.logged,
};
}
const mapDispatchToProps = {
setLogged,
};
export default connect(mapStateToProps, mapDispatchToProps)(LoginPage);
The Login component inside LoginPage, is only a form and it is not necessary to go into details of it. The "setLogged" action only saves a JSON with user data and a session token, and changes the "isLogged" variable from the reducer to "true". This action is working properly.
The problem I have is the following. When the user logs in, the "LoginPage" component correctly detects the status variable "userLogged.isLogged" changes to "true", so it renders the <Redirect>
to the "Dashboard" component, but the protected path of the component "Dashboard" does not detect it (at least it seems so).
If I place the protected route outside the "IonRouterOutlet" it works perfect. But I need it to be inside the "IonRouterOutlet" because I need to access an event of the Ionic pages (useIonViewDidEnter). How can i fix this? Either by operating the protected route correctly from within the "IonRouterOutlet", or somehow simulating the "useIonViewDidEnter".
I already tried the following protected routes:
<Route exact path="/dashboard"
component={userLogged.isLogged ? Dashboard : LoginPage}
/>
<Route exact path="/dashboard"
render={props => {
return userLogged.isLogged ? <Dashboard {...props} /> : <LoginPage />;
}}
/>
Thanks in advance
There was a bug fixed in one of the most recent versions that refreshed the closures created for the routes. After upgrading @ionic/react and @ionic/react-router to version 4.11.8, I can confirm that the bug is fixed. Also have to update @types/react to 16.9.19, and @types/react-router to 5.1.4, to avoid issues like this