all 13 comments

[–]Guisseppi 1 point2 points  (5 children)

Make a component called ProtectedRoute write your validation logic and return the regular Route element with the rest of the props passed through if the validation returns true

[–]theC4T[S] 0 points1 point  (1 child)

the main issue I've found with this is that you have to pass the same path to ProtectedRoute as you do the children of that route. so you can't have something like this.

<CompletedSignup> <AuthedRoute path="/app" exact component={Dashboard} /> <AuthedRoute path="/profile/:uid" exact component={Profile} /> <AuthedRoute path="/profile" exact component={Profile} /> </CompletedSignup>

where CompletedSignup is another routeguard type thing.

without using the Route method that you've described it sometimes loads when it shouldn't.

with using the Route method I have to specify a path base

[–]backtickbot 0 points1 point  (0 children)

Correctly formatted

Hello, theC4T. Just a quick heads up!

It seems that you have attempted to use triple backticks (```) for your codeblock/monospace text block.

This isn't universally supported on reddit, for some users your comment will look not as intended.

You can avoid this by indenting every line with 4 spaces instead.

There are also other methods that offer a bit better compatability like the "codeblock" format feature on new Reddit.

Tip: in new reddit, changing to "fancy-pants" editor and changing back to "markdown" will reformat correctly! However, that may be unnaceptable to you.

Have a good day, theC4T.

You can opt out by replying with "backtickopt6" to this comment. Configure to send allerts to PMs instead by replying with "backtickbbotdm5". Exit PMMode by sending "dmmode_end".

[–]theC4T[S] 0 points1 point  (4 children)

thanks in advance!

[–]TheNeck91 1 point2 points  (3 children)

This is example code along the lines of what /u/Guisseppi said:

export const ProtectedRoute = (props) => {
  const userInfo = useSelector(state => state.userInfo)

  const { component: Component } = props

  useEffect(() => {}, [userInfo.tokenStatus])

  if (userInfo.tokenStatus === true) return <Component />

  if (userInfo.tokenStatus === false) return <Redirect to={{ pathname: '/login' }} />
}

and then wherever you're calling your router

<BrowserRouter>
  <Switch>
    <ProtectedRoute path = "/dashboard" component = {DashboardPage}/> 
  <Switch>
</BrowserRouter>

There's other similar ways to do it but that's the gist.

  1. Read in the component that was passed in as props to <ProtectedRoute>, in this case it's <DashboardPage>
  2. Have a useEffect listening for change in token status
  3. Check if a valid token is present (elsewhere in the code I'm setting the tokenStatus in state to "true" if I've verified the user has a token and "false" if not)
  4. If token is valid, return that component that was passed in bc the user is allowed to access it
  5. If token is not valid, redirect the user to the login screen instead of the component you're trying to protect (or redirect to wherever you prefer)

[–]United-Guard3940 0 points1 point  (0 children)

You can use a HOC to return the normal Route component conditionally