I'm fairly new to React and Ionic. What I'm attempting to accomplished is to create a "protected route". I create a simple context called AuthContext
:
import { createContext, Dispatch } from 'react';
/**
* Context interface for AuthAuthentication/Authorization
*
* @property isAuthenticated
* @property dispatch
*
* @interface
*/
interface AuthDefaultContext {
isAuthenticated: boolean;
dispatch: Dispatch<any>
}
/**
* Authentication/Authorization context for managing
* authenticating/ed and authorizing/ed users
*/
export const AuthContext = createContext<AuthDefaultContext>({
isAuthenticated: false,
dispatch: () => {}
});
and FunctionalComponent called ProtectedRoute
:
interface ProtectedRouteProps {
ProtectedComponent: FunctionComponent,
routePath: string
}
export const ProtectedRoute: FunctionComponent<ProtectedRouteProps> = ({ ProtectedComponent, routePath }) => {
useEffect(() => {
console.log(`loading protected route '${routePath}' with component ${ProtectedComponent.name}`)
}, [ProtectedComponent, routePath] );
return (
<AuthContext.Consumer>
{
({ isAuthenticated }) => (
<Route path={ routePath } render={ () => isAuthenticated ? <ProtectedComponent/> : <Redirect to="/login" /> }/>
)
}
</AuthContext.Consumer>
);
}
In my main app component I wrap the IonReactRouter
inside the AuthContext.Provider
like so:
<IonApp>
<AuthContext.Provider value={{ isAuthenticated: authenticated, dispatch: dispatch }}>
<IonReactRouter>
<IonRouterOutlet>
<Route path="/login" component={ Login } exact={ true } />
<ProtectedRoute routePath="/welcome" ProtectedComponent={ Welcome }/>
<ProtectedRoute routePath="/search" ProtectedComponent={ Dummy }/>
</IonRouterOutlet>
</IonReactRouter>
</AuthContext.Provider>
</IonApp>
The issue that I am having is that above works fine for the regular Route and first ProtectedRoute, but the /search/
does not work. The uri path changes in the browser url to /search
but the dummy component doesn't render.
I noticed that if you swap <IonReactRouter>
& <IonRouterOutlet>
like so:
<IonRouterOutlet>
<IonReactRouter>
.....
</IonReactRouter>
</IonRouterOutlet>
all of the routes works but you lose the animation effect provided by the IonRouterOutlet
. The navigation docs on Ionics website has the IonReactRouter
wrapping IonRouterOutlet
so I am assuming that's the correct implementation.
If I change the ProtectedRoute
's to just the standard react Route
all routes work fine with the animations. So the issue has to be with my Implementation of the ProtectedRoute
component, I just can't figure it out. Any help would be most appreciated. Thank you!
UPDATE:
I still haven't found a solution for this issue, so I removed the IonRouterOutlet which seems to be the root cause. When doing so, everything works as expected. I posted this issue on the Ionic forum so when/if I get an answer, I'll post it here.
Thanks,
IonRouterOutlet expects its children to be either Routes or "Route like", which means the children need to have the same basic props that a Route does.
So, for your ProtectedRoute, it should work if you rename your incoming props routePath
to path
and ProtectedComponent
to component
.
I put together a working sample repo starting with your code here: https://github.com/elylucas/ionic-react-protected-route
Let me know if that helps.
Thanks
I've found that using the render
prop on a Route
in an IonRouterOutlet
breaks it.
In your case you would have to replace the following:
<Route
path={routePath}
render={() => isAuthenticated ? <ProtectedComponent/> : <Redirect to="/login" />}
/>
With something like this:
{
isAuthenticated ?
<Route path={routePath} component={ProtectedComponent} /> :
<Redirect to="/login" />
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With