Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using render in react router dom with a private route

Im trying to render two components within a private route using react router dom v4. This is possible using a normal Route but it does not seem to be the case when using a custom Route. I get the following error: "Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports. "

Custom route (Authenticated)
return (
      <Route
        {...rest}
        render={props =>
          this.currentUser()
            ? <Component currentUser={this.currentUser} {...props} />
            : <Redirect
                to={{
                  pathname: '/auth/login',
                  state: { from: props.location }
                }}
              />
        }
      />
    )
Then in my routes i want something like this
return (
      <div>
        <Switch location={isModal ? this.prevLocation : location}>
          <Authenticated path="/" exact component={Main} />
          <Route path="/auth/register" exact component={Register} />
          <Route path="/auth/login" exact component={Login} />
          <Authenticated
            path="/clients/:id/edit"
            render={(props) => ( // Not working as expected. Works fine using Route instead of Authenticated
              <div>
                <Main />   
                <ClientEdit />
              </div>
            )}
          />
        </Switch>
        {isModal ?
          <Authenticated
            path='/clients/new'
            component={ClientNew}
          />
        : null}
        {isModal ?
          <Authenticated
            path='/clients/:id/edit'
            component={ClientEdit}
          />
        : null}
      </div>
    );
like image 476
adavia Avatar asked Dec 20 '17 15:12

adavia


People also ask

How do I restrict access to routes in react router?

To restrict access to routes in React Router, we set the render prop to a function that renders the component we want according to the condition we're checking. import { Route, Redirect } from "react-router"; <Route exact path="/" render={() => (loggedIn ?

Can we use render in route?

Route render methods There are, however, a few other methods you can use to render something with a <Route> . These are provided mostly for supporting apps that were built with earlier versions of the router before hooks were introduced. You should use only one of these props on a given <Route> .

What is the purpose of private route?

The private route component is used to protect selected pages in a React app from unauthenticated users.


2 Answers

I'm a little late, but for anyone still needing this, I found that this works for me.

export function PrivateRoute({ component: Component = null, render: Render = null, ...rest }) {
  const authService = new AuthService();

  return (
    <Route
      {...rest}
      render={props =>
        authService.isAuthenticated ? (
          Render ? (
            Render(props)
          ) : Component ? (
            <Component {...props} />
          ) : null
        ) : (
          <Redirect to={{ pathname: '/login', state: { from: props.location } }} />
        )
      }
    />
  );
}

And in my routes I use it like so:

<PrivateRoute
    path="/some-route/edit"
    render={props => <MyComponent {...props} isAwesome={true} />} />
like image 76
Justin Ross Avatar answered Nov 15 '22 03:11

Justin Ross


In your protectedRoute component, you are not receiving or utilizing render prop which you are sending in the line:

render={(props) => ( 
  <div>
    <Main />   
    <ClientEdit />
  </div>
)}

instead of using render send the component in component prop like :

component={(props) => ( 
  <div>
    <Main />   
    <ClientEdit />
  </div>
)}

Also check react router's docs to see when to use component prop and when to use render prop. It would be much better if you can change your protectedRoute to handle both.

like image 25
sudheer singh Avatar answered Nov 15 '22 03:11

sudheer singh