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>
);
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 ?
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> .
The private route component is used to protect selected pages in a React app from unauthenticated users.
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} />} />
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.
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