简体   繁体   中英

React Router doesn't access Protected Route

In my typescript react project i have created a protected route to check for authenticationbefore rendering a component.

export const ProtectedRoute: React.FC<ProtectedRouteProps> = props =>{

    const currentLocation = useLocation();

    let redirectpath = props.redirectPathOnAuthentication;
    console.log(redirectpath)
    console.log('in protected route')
    if(!props.isAuthenticated){
        props.setRedirectPathOnAuthentication(currentLocation.pathname);
        redirectpath = props.authenticationPath;
    }

        if(redirectpath !== currentLocation.pathname){
            const renderComponent = () => <Redirect to={{pathname: redirectpath}} />;
            return <Route {...props} component={renderComponent} render={undefined} />
        }else{
            return <Route {...props} />
        }
    }

I pass in the props to make conditional rendering based, on rather the user is authenticated or not. I have the tries to access a ProtectedRoute, the user will be redirected to the route where login is possible ( named as /home route), and then redirected back to the original route.

   
export const RoutingHandler: React.FC = (props: Props) => {
    
    const location = useLocation()
    
    const [sessionContext, updateSessionContext] = useSessionContext()
    console.log(location)

    const setRedirectPathOnAuthentication = (path: string) =>{
        updateSessionContext({...sessionContext, redirectPathOnAuthentication: path})
    }

    const defaultProtectedRouteProps: ProtectedRouteProps = {
        isAuthenticated: !!sessionContext.isAuthenticated,
        authenticationPath: '/home',
        redirectPathOnAuthentication: sessionContext.redirectPathOnAuthentication || '',
        setRedirectPathOnAuthentication
    }

    console.log(defaultProtectedRouteProps)

    return (
        <div>
        <Navbar />
        <Switch>
        <ProtectedRoute {...defaultProtectedRouteProps} path="/dashboard" component={Dashboard} />
        <Route exact path="/home" component={Home} />
        <Route path="/about" component={About} />
        <Route path="/help" component={Help} />
        <Redirect from="/" to="/home" />
        </Switch>
        </div>
    )
}

Whenever I do `history.push('/dashboard');` the `Dashboard` component is never rendered.

For desired implementation, you can try this approach, that works fine:

export const PrivateRoute = ({component: Component, isAuthenticated, ...rest}) => (
    <Route {...rest} 
        render={
            props => (
                isAuthenticated ? (
                    <Component {...props} />
                ):
                (
                    <Redirect to={{ pathname: '/login', state: { from: props.location }}}/>
                )
            )
        }
    />
)

PrivateRoute.propTypes = {
    isAuthenticated: PropTypes.bool.isRequired
}

const mapStateToProps = state => ({
  isAuthenticated: state.auth.isAuthenticated
});


export default connect(mapStateToProps)(PrivateRoute)

so, in DefaultsRoutes :

<Switch>
     <Route path="/login" component={Login} />
     <Route path="/signup" component={Signup} />
     <PrivateRoute component={Home} />
     <Route path="*" component={NotFound404} />
</Switch>

in App :


let AppRedirect = ({ loadingApp }) => {
  return loadingApp ? <Loading /> : <DefaultRoutes />;
};

const mapState = (state) => ({
  loadingApp: state.app.loadingApp,
});

AppRedirect = connect(mapState)(AppRedirect);

export class App extends React.Component {

  render() {
    return (
      <Provider store={store}>
          <AppRedirect />
      </Provider>
    );
  }
}

export default App;

When user successfully logged in dispatch an action to change state: loadingApp: true -> loadingApp: false

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM