React Router v4 Nested Routes with Switch - javascript

Trying to do the following, but it's not working.
ReactDOM.render(
<Router>
<div className="route-wrapper">
<Switch>
<App>
<Route exact path="/" component={HomePage} />
<Route path="/user" component={UserPage} />
</App>
<Route component={Err404} />
</Switch>
</div>
</Router>,
document.getElementById('main')
)
As the documentation says only Route and Redirect elements are allowed inside a Switch element. How do I get this to work without explicitly wrapping HomePage and UserPage in App or having the error page wrapped by App?

While I have begun developing a "Universal React app", where the first page load is done with server-side rendering, I faced similar problem as the React-Router had just updated to 4.0. You should consider restructuring you application something as given below:
ReactDOM.render(
<Router>
<div className="route-wrapper">
<Switch>
<Route path="/" component={App} />
<Route component={Err404} />
</Switch>
</div>
</Router>,
document.getElementById('main')
)
Where the App component is refactored as following:
class App extends React.Component {
render() {
return <div>
<Switch>
<Route exact path="/" component={HomePage} />
<Route exact path="/user" component={UserPage} />
</Switch>
</div>;
}
}

Related

Layout is not a <Route> component. All component children of <Routes> must be a <Route> or <React.Fragment>. How should I overcome this error?

<Routes>
<Route exact path='/'>
<Layout>
<Home></Home>
</Layout>
</Route>
</Routes>
Layout consists of header and footer, I want to wrap my home inside Layout.
React 18.1.0
react-router-dom 6.0.2
Other Route components are the only valid children of a Route component. This is the use case of building nested routes. For routed content/components, these must use the element prop.
Render the Layout component as the element of the Route component.
Example:
<Routes>
<Route
path='/'
element={(
<Layout>
<Home />
</Layout>
)}
/>
</Routes>
It also common to have layout components render an Outlet for nested routes.
Example:
const Layout = () => (
<>
<Header />
<Outlet />
<Footer />
</>
);
...
<Routes>
<Route element={<Layout />}>
<Route path='/' element={<Home />} />
</Route>
</Routes>
You could just extract the <Home/> component from there and provide the layout as a prop to the Route like this
<Route component={Layout} />
And provide your home component inside the Layout component it self

react router not rendering components at route

My root component is shown below:
ReactDOM.render(
<Provider store={store}>
<Router>
<Menu />
<Switch>
<Route path='/'>
<Home />
</Route>
<Route path='/about'>
<About />
</Route>
</Switch>
</Router>
</Provider>,
document.getElementById('root')
)
and then my Menu component is shown below:
function Menu() {
return (
<ul className='menu'>
<li className='menu-item'>
<Link to='/'>Home</Link>
</li>
<li className='menu-item'>
<Link to='/about'>About</Link>
</li>
</ul>
)
}
export default withRouter(Menu)
The problem is that when I click the relevant link, my About component does not render but the url shows up in the url bar. I am not sure what's wrong and I have gone through all of the questions related to this topic and none of their suggestions have helped me. I am using redux but I do not think that is what is causing the problem. Please help!
As mentioned, the exact prop should be added to the route that renders the Home component:
<Router>
...
<Route exact path="/" component={Home} />
<Route path="/about" component={About} />
...
</Router>
The reason for that is to restrict rendering of the Home component to an exact match of "/". Without the exact prop, the Home component will also be rendered for other partially matched routes (ie "/about", which would be considered a partial match).
Some other suggestions; you might consider assigning the component rendered for a route via the component prop on the Route component by doing this:
<Route exact path="/" component={Home} />
Additionally, you can avoid wrapping the Menu component with the withRouter.
For a working example, see this link - hope these pointers help! :)
add exactto your rout, like this
<Route exact path='/'>
<Home />
</Route>
<Route exact path='/about'>
<About />
</Route>
Use the Router logic like this.
<Provider store={store}>
<Router>
<Menu />
<Switch>
<Route path='/' exact component = {Home}/>
<Route path='/about' exact component = {About}/>
</Switch>
</Router>
</Provider>,

React + TypeScript with router deployement issue on Github Pages

Local runs fine, but when run on "npm run deploy" the website returns 404.
I have a React + TypeScript app which utilises react-router-dom BrowserRouter to navigate between pages.
I am ware of the issue on github pages with react-router, therefore I have tried adding basename={process.env.PUBLIC_URL}, changing it to a HashRouter, and many many more possibilities.
I've been on this issue for 7 hours straight... and there seems to be no resources on this particular problem for Typescript.
Could someone please help me!
index.tsx
ReactDOM.render(
<AppRouter />,
document.getElementById('root') as HTMLElement
);
Router.tsx
export const AppRouter: React.StatelessComponent<{}> = () => {
return (
<BrowserRouter basename={process.env.PUBLIC_URL}>
<div>
<NavBar />
<Switch>
<Route exact={true} path='/' component={App} />
<Route exact={true} path='/' component={Notes} />
<Route exact={true} path='/About' component={About} />
</Switch>
</div>
</BrowserRouter>
);
Also tried Router.tsx
export const AppRouter: React.StatelessComponent<{}> = () => {
return (
<HashRouter>
<div>
<NavBar />
<Switch>
<Route exact={true} path='/' component={App} />
<Route exact={true} path='/' component={Notes} />
<Route exact={true} path='/About' component={About} />
</Switch>
</div>
</HashRouter>
);
NavBar.tsx
export const NavBar: React.StatelessComponent<{}> = () => {
return (
<div id='nav-bar'>
<AppBar position='static' color='default'>
<Toolbar>
<span id='navbar-title'>
<Typography variant='title' color='default'>
Keep
</Typography>
</span>
<Link to="/">
<Button size="large" color="primary" variant="text">Notes</Button>
</Link>
<Link to="/About">
<Button size="large" color="primary" variant="text">About</Button>
</Link>
</Toolbar>
</AppBar>
</div>
)
Thank you for reading.
EDIT below is the exact error response from web console at 404 error. Something about favicon, could that be an issue? The location is completely wrong
json469.github.io/:1 Refused to load the image 'https://json469.github.io/favicon.ico' because it violates the following Content Security Policy directive: "img-src data:".
I've also tried debugging by printing out the process.env.PUBLIC_URL, however it returned an empty string...
EDIT2 below is the change made to Router.tsx that fixed the issue.
<HashRouter>
<div>
<NavBar />
<main>
<Switch>
<Route exact={true} path='/' component={App} />
<Route exact={true} path='/' component={Notes} />
<Route exact={true} path='/About' component={About} />
</Switch>
</main>
</div>
</HashRouter>
This is unlikely to be due to TypeScript - or even React Router. If you receive a 404, that is because your server has to redirect the user to your React app if they visit a route that the server does not know, and your app can then pretend to do actual routing.
However, it appears that GitHub Pages does not support this. Thus, you cannot do "proper" URLs like username.github.io/page/some-route. A workaround is to use the Hash Router, as you mentioned, but that means that URLs will look like username.github.io/page#/some-route.
Thus, your issue is probably that you're trying the former route, rather than the latter. So to solve it, you can either try that kind of route, or move to a different host.

Multiple entry point in webpack

I want to use multiple entry point for login like '/user/login' & '/admin/login'. I am bit confused about this. Should I use separate files for this, or IS there any way where I can use multiple entry point using the same file? I am using react.js
React Router 4 is a great router for React that allows you to configure paths like this:
<BrowserRouter>
<Switch>
<Route path="/user/login" component={LoginComponent} />
<Route path="/admin/login" component={LoginComponent} />
<Route path="/blueberry/login" component={LoginComponent} />
<Route path="/user/signin" component={LoginComponent} />
<Route path="/admin/signin" component={LoginComponent} />
<Route path="/blueberry/signin" component={LoginComponent} />
</Switch>
</BrowserRouter>
You can also use RegEx to simplify:
<BrowserRouter>
<Switch>
<Route
path="/(user|admin|blueberry)/(login|signin)"
component={LoginComponent} />
</Switch>
</BrowserRouter>

react router v4 route changed but did not render the correct component

I have 2 level of route, the first layer it look like this
<BrowserRouter>
<div>
<AuthRoute></AuthRoute>
<Switch>
<Route path='/dashboard' component={Dashboard} />
</Switch>
</div>
</BrowserRouter>
where in AuthRoute I have a redirect upon componentDidMount
this.props.history.replace(/dashboard/redirected)
The problem is within the dashboard/index which is my 2nd level of route config
<BrowserRouter>
<Switch>
<Route exact path='/dashboard' component={()=><h1>dashboard index</h1>} />
<Route exact path='/dashboard/somewhere' component={()=><h1>somewhere</h1>} />
<Route exact path='/dashboard/redirected' component={() => <h1>redirected</h1>} />
</Switch>
</BrowserRouter>
The route changed to /dashboard/redirect but the component didn't render the correct one if you refresh on says /dashboard/somewhere or /dashboard/
You can see the problem clearer in the demo I setup https://codesandbox.io/s/v0v4qok38l
You only need one <BrowserRouter> in the application - removing it from dashboard/index.js will fix your issue.

Categories

Resources