I have a Router component in my react app. Which will have 4 different types of layout.
1- Public routes like login and signup that have no layout.
2- User routes that will have UserLayout component.
3- Admin routes that will have AdminLayout component.
4- Anything other than those above should render Error404 component.
Here's my Router component:
<BrowserRouter>
<Switch>
<Route path="/" exact render={() => <Redirect to='/user/signin' />} />
<Route path='/oauth/:token' component={Oauth} />
<Route path='/user/signin' component={Signin} />
<Route path='/admin/signin' component={Signin} />
<Route path='/user/signup/:username' component={Signup} />
<Route path='/user/signup' component={Signup} />
<Route path='/oauth' exact render={() => <Redirect to={'/user/dashboard'} />} />
<Route path='/user/reset' component={Reset} />
<ProtectedRoute path='/user/auth2fa' component={TwofactorForm} />
<ProtectedRoute path='/admin' exact component={Error404} />
<ProtectedRoute path='/user' exact component={Error404} />
<Route path='/user'>
<UserLayout>
<Switch>
//bunch of user routes
</Switch>
</UserLayout>
</Route>
<Route path='/admin'>
<AdminLayout>
<Switch>
//bunch of admin routes
</Switch>
</AdminLayout>
</Route>
<ProtectedRoute component={Error404} />
</Switch>
</BrowserRouter>
My problem is the 404 page. If someone goes to /user* URL that does not match the routes inside layout, they will see an empty user layout page. Same thing goes for /admin*. And if I nest the Error404 component at the end of Switch inside layout components, the result would be a layout page with a 404 page inside of it which is not what I want. How can I achieve this?
Important note: I don't want the layout components to get re-rendered on URL change. Because they are stateful and I use the header to connect to websockets, which is not ideal to reconnect to websocket on every URL change