How to send props using render in reachrouterdomv6? - javascript

I am learning from udemy but that course is from v5.I dont know what is equivalent to render and how to send props with it ? Also, in bottom of the code if element is undefined it should go to "NotFound" but its not working too.
<Routes>
<Route
exact
path="/home"
render={(props) => (
<ProductList
{...props}
products={this.state.products}
currentCategory={this.state.currentCategory}
info={productInfo}
addToCart={this.addToCart}
/>
)}
></Route>
<Route exact path="/cart" element={<CartList />} />
<Route element={<NotFound />} />
</Routes>

<Routes>
<Route exact path="/" element={<ProductList
{...this.props}
products={this.state.products}
currentCategory={this.state.currentCategory}
info={productInfo}
addToCart={this.addToCart}
/>}></Route>
<Route exact path="/cart" element={<CartList />} />
<Route path="*"element={<NotFound />} />
</Routes>
I solved.

In the v6 you can pass props directly to the element. No need to use render anymore
<Route exact path="/cart" element={<CartList {...props} />} />

Related

How to load multiple routes in index file using react

I have a following index file -
<BrowserRouter>
<Routes>
<Route path="/" element={Home}
<Route element={Navigation}
</Routes>
</BrowserRouter>
I have multiple routes which I have to load So For that I have written a component:
const Navigation = () => {
<>
<Route path="/not-available-primary" element={NotAvaliable}/>
<Route path="/not-available-Secondary" element={Avaliable}/>
<Route path="/available-primary" element={Primary}/>
<Route path="/available-Secondary" element={Secondary}/>
<Route path="/direct-debit-primary" element={DirectDBB}/>
<Route path="/direct-debit-secondary" element={DirectDBBSecondary}/>
</>
}
But here, it does not render the component and gives no routes matched for location.
How do I fix this ?
You have to give a Component to the element prop, like this:
<BrowserRouter>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/*" element={<Navigation />} />
</Routes>
</BrowserRouter>
and
const Navigation = () => {
return (<>
<Route path="/not-available-primary" element={<NotAvaliable />}/>
<Route path="/not-available-Secondary" element={<Avaliable />}/>
<Route path="/available-primary" element={<Primary />}/>
<Route path="/available-Secondary" element={<Secondary />}/>
<Route path="/direct-debit-primary" element={<DirectDBB />}/>
<Route path="/direct-debit-secondary" element={<DirectDBBSecondary />}/>
</>)
}
or
<BrowserRouter>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/*">
<Route path="not-available-primary" element={<NotAvaliable />}/>
<Route path="not-available-Secondary" element={<Avaliable />}/>
<Route path="available-primary" element={<Primary />}/>
<Route path="available-Secondary" element={<Secondary />}/>
<Route path="direct-debit-primary" element={<DirectDBB />}/>
<Route path="direct-debit-secondary" element={<DirectDBBSecondary
/>}/>
</Route>
</Routes>
</BrowserRouter>
Note that in the seconds solution (nested routes) I erased the "/".
Documentation here
in your index file
<Route path="/" compoment={Home}
if "Navigation" is your class
const Navigation = () => {
return (
<>
<Routes>
<Route path="/not-available-primary" component={NotAvaliable}/>
<Route path="/not-available-Secondary" component={Avaliable}/>
<Route path="/available-primary" component={Primary}/>
<Route path="/available-Secondary" component={Secondary}/>
<Route path="/direct-debit-primary" component={DirectDBB}/>
<Route path="/direct-debit-secondary" component={DirectDBBSecondary}/>
</Routes>
</>
)
}
Issue
It's unclear which version of react-router-dom you are trying to use. version 4/5 or 6, but you've syntax issues for either. The route rendering the Navigation component needs a path with a trailing "*" character to be matched at the root/base level so the descendent routes can then also be matched and rendered.
Using react-router-dom#5
Use the Switch component instead of the Routes component. The Route components use the component (or render or children function props). The home path "/" must exactly match in order for any other route to be matched when the path isn't exactly "/", e.g. "/not-available-primary".
<BrowserRouter>
<Switch>
<Route path="/" exact component={Home} />
<Route path="*" component={Navigation} />
</Switch>
</BrowserRouter>
...
const Navigation = () => {
<Switch>
<Route path="/not-available-primary" component={NotAvaliable} />
<Route path="/not-available-Secondary" component={Avaliable} />
<Route path="/available-primary" component={Primary} />
<Route path="/available-Secondary" component={Secondary} />
<Route path="/direct-debit-primary" component={DirectDBB} />
<Route path="/direct-debit-secondary" component={DirectDBBSecondary} />
</Switch>
};
Using react-router-dom#6
All Route components can only be rendered by a Routes component or another Route component in the case of route nesting. The Route component API changed significantly and there is now only a single element prop taking a ReactNode, a.k.a. JSX, as a value. In RRDv6 all routes are now always exactly matched and use a route ranking system; there is no longer an exact prop for Route components.
<BrowserRouter>
<Routes>
<Route path="/" element={<Home />} />
<Route path="*" element={<Navigation />} />
</Routes>
</BrowserRouter>
...
const Navigation = () => {
<Routes>
<Route path="/not-available-primary" element={<NotAvaliable />} />
<Route path="/not-available-Secondary" element={<Avaliable />} />
<Route path="/available-primary" element={<Primary />} />
<Route path="/available-Secondary" element={<Secondary />} />
<Route path="/direct-debit-primary" element={<DirectDBB />} />
<Route path="/direct-debit-secondary" element={<DirectDBBSecondary />} />
</Routes>
};
At the first use <Switch> in Navigation component :
const Navigation = () => {
<Switch>
<Route path="/not-available-primary" component={NotAvaliable}/>
<Route path="/not-available-Secondary" component={Avaliable}/>
<Route path="/available-primary" component={Primary}/>
<Route path="/available-Secondary" component={Secondary}/>
<Route path="/direct-debit-primary" component={DirectDBB}/>
<Route path="/direct-debit-secondary" component={DirectDBBSecondary}/>
</Switch>
}
so, add the component to Route:
<BrowserRouter>
<Switch>
<Route path="/" exact component={Home} />
<Route path="/login" exact component={LoginForm} />
<Route component={Navigation} />
</Switch>
</BrowserRouter>

React multiple pages using react-router-dom

I m trying to make multiple react pages but react doesn't show any of the new pages . I think my code is correct , I am using npm install react-router-dom#6
and this is my code :
Index.js
ReactDOM.render(
<BrowserRouter>
<Routes>
<Route path="/" element={<App />}>
<Route path="pricing" element={<Pricing />} />
<Route path="contact" element={<Contact />} />
</Route>
</Routes>
</BrowserRouter>,
document.getElementById('root')
);
in the Navbar.jsx :
<Link to="/pricing">Pricing</Link>
<Link to="/contact">Contact</Link>
and for example Pricing.js :
<div className='Pricing'>
<Navbar />
</div>
Any idea how to fix this ? where I have missed it exactly ?
First you are missing / on some path. Second, the first Route will catch all of them, because all of them start with /. To avoid that, you need the keyword exact, like so:
ReactDOM.render(
<BrowserRouter>
<Routes>
<Route exact path="/" element={<App />} />
<Route exact path="/pricing" element={<Pricing />} />
<Route exact path="/contact" element={<Contact />} />
</Routes>
</BrowserRouter>,
document.getElementById('root')
);
/ is missing in your code and also use exact property to match exact URL.
ReactDOM.render(
<BrowserRouter>
<Routes>
<Route path="/" exact element={<App />}>
<Route path="/pricing" exact element={<Pricing />} />
<Route path="/contact" exact element={<Contact />} />
</Route>
</Routes>
</BrowserRouter>,
document.getElementById('root')
);

How to go specific route without rendering some components in React?

I am using react-router-dom v6. I want my Login page to be rendered without the Sidebar and Topbar components. How to do it?
function App() {
return (
<Router>
<Container>
<Sidebar />
<Content>
<Topbar />
<MainContent>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/users" element={<UserList />} />
<Route path="/users/:id" element={<User />} />
<Route path="/newUser" element={<NewUser />} />
<Route path="/products" element={<ProductList />} />
<Route path="/products/:id" element={<Product />} />
<Route path="/newProduct" element={<NewProduct />} />
<Route path="/login" element={<Login />} />
</Routes>
</MainContent>
</Content>
</Container>
</Router>
);
}
I don't want my login page to render inside the MainContent but taking the whole page without Sidebar and Topbar.
I tried moving the Routes upper and have the login route above the sidebar but there is an error Error: [Sidebar] is not a <Route> component. All component children of <Routes> must be a <Route> or <React.Fragment>
Since SideBar and TopBar appear to be part of a "layout", and you want a different "layout" specifically for "/login" then I suggest abstracting the container components into layout components. Each layout container should render an Outlet for their respective nested routes.
const AppLayout = () => (
<Container>
<Sidebar />
<Content>
<Topbar />
<MainContent>
<Outlet />
</MainContent>
</Content>
</Container>
);
const LoginLayout = () => (
<Container>
<Content>
<MainContent>
<Outlet />
</MainContent>
</Content>
</Container>
);
...
function App() {
return (
<Router>
<Routes>
<Route path="/" element={<AppLayout />}>
<Route index element={<Home />} />
<Route path="users" element={<UserList />} />
<Route path="users/:id" element={<User />} />
<Route path="newUser" element={<NewUser />} />
<Route path="products" element={<ProductList />} />
<Route path="products/:id" element={<Product />} />
<Route path="newProduct" element={<NewProduct />} />
</Route>
<Route path="/login" element={<LoginLayout />}>
<Route index element={<Login />} />
</Route>
</Routes>
</Router>
);
}
function App() {
return (
<Router>
<Container>
{
Login || <Sidebar />
}
<Content>
{
Login || <Topbar />
}
<MainContent>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/users" element={<UserList />} />
<Route path="/users/:id" element={<User />} />
<Route path="/newUser" element={<NewUser />} />
<Route path="/products" element={<ProductList />} />
<Route path="/products/:id" element={<Product />} />
<Route path="/newProduct" element={<NewProduct />} />
<Route path="/login" element={<Login />} />
</Routes>
</MainContent>
</Content>
</Container>
</Router>
);
}
try conditional rendering. It works for me!

React how can i redirect the homepage?

My problem is ı have a routes like that but when i try for example http://localhost:3000/examp1
I just want to redirect to HomePage how can i do that when i write something http://localhost:3000/*** ı go the page but nothing shows how can i detect and how can i redirect the homepage ? anyone help ?
<Router>
<Switch>
<Route path='/' component={Home} exact />
<Route path='/xyz' component={asf} exact />
<Route path='/asd' component={asd} exact />
<Route path='/fasd/:slug' component={asd} exact />
<Route path='/asd' component={asd} exact />
<Route path='/asd/:slug' component={asd} exact />
<Route path='/asd' component={asd} exact />
<Route path='/asd' component={fas} exact />
<Route path='/asd' component={fasd} exact />
</Switch>
</Router>
Adding a <Route /> at the bottom without a path attribute inside the <Switch> tag should work for when there's no match, and then use a <Redirect /> tag to redirect to the homepage.
<Router>
<Switch>
<Route path='/' component={Home} exact />
<Route path='/xyz' component={asf} exact />
<Route path='/asd' component={asd} exact />
<Route path='/fasd/:slug' component={asd} exact />
<Route path='/asd' component={asd} exact />
<Route path='/asd/:slug' component={asd} exact />
<Route path='/asd' component={asd} exact />
<Route path='/asd' component={fas} exact />
<Route path='/asd' component={fasd} exact />
<Route component={() => <Redirect to="/" />} />
</Switch>
</Router>
How to properly render a 404 page in React with React-Router?
https://reactrouter.com/web/api/Redirect
You can simply use Redirect component of react-router-dom library.
<Router>
<Switch>
<Route path='/' component={Home} exact />
<Route path='/xyz' component={asf} exact />
<Route path='/asd' component={asd} exact />
<Route path='/fasd/:slug' component={asd} />
<Route path='/asd' component={asd} exact />
<Route path='/asd/:slug' component={asd} />
<Redirect to="/" />
</Switch>
</Router>
DefaultRoute and NotFoundRoute were removed in react-router 1.0.0.
I'd like to emphasize that the default route with the asterisk has to be last in the current hierarchy level to work. Otherwise it will override all other routes that appear after it in the tree because it's first and matches every path.
For react-router 1, 2 and 3
If you want to display a 404 and keep the path (Same functionality as NotFoundRoute)
<Route path='*' exact={true} component={My404Component} />
If you want to display a 404 page but change the url (Same functionality as DefaultRoute)
<Route path='/404' component={My404Component} />
<Redirect from='*' to='/404' />
Example with multiple levels:
<Route path='/' component={Layout} />
<IndexRoute component={MyComponent} />
<Route path='/users' component={MyComponent}>
<Route path='user/:id' component={MyComponent} />
<Route path='*' component={UsersNotFound} />
</Route>
<Route path='/settings' component={MyComponent} />
<Route path='*' exact={true} component={GenericNotFound} />
</Route>
For react-router 4 and 5
Keep the path
<Switch>
<Route exact path="/users" component={MyComponent} />
<Route component={GenericNotFound} />
</Switch>
Redirect to another route (change url)
<Switch>
<Route path="/users" component={MyComponent} />
<Route path="/404" component={GenericNotFound} />
<Redirect to="/404" />
</Switch>
The order matters!
I ma using Navigate to redirect from "/" to "/home"
import {BrowserRouter, Navigate, Route, Routes,} from "react-router-dom";
<BrowserRouter>
<Routes>
<Route exact path="/" element={<Navigate to="/home"/>} />
</Routes>
</BrowserRouter>

Nested route is not working as expected - React router

My code is
<Switch>
<Route path='/' exact render={() => <Redirect to='/route' />} />
<Route path='/route/' exact render={() => <Component />} />
<Route path='/route/subroute/:id+' exact render={() => <Component1/>} />
<Route path='/route/subroute/subsubroute1/:id+' exact render={() => <Component2 />} />
<Route path='/route/subroute/subsubroute2/:id+' exact render={() => <Component3 />} />
<Route path='/route/:subroute+' exact render={() => <Component4 />} />
<Route render={() => <Redirect to='/notfound' />} />
</Switch>
Now when I am hitting history.push(/route/subroute/id) it is working
But when I try to open history.push(/route/subroute/subroute1/id) it is not opening page for me. I tried to go through the documents but all things seem to be in place. What am i missing.
+ operator at /route/subroute/:id+ makes you match /route/subroute/subsubroute1/123 for Component1 route, with a param subsubroute1/123.
remove the + and it should work as expected.
alternatively, if you really need to use +, you can move down Component1, and Component2 will be matched properly since react-router-dom matches the first route that matches the given path:
<Switch>
<Route path='/' exact render={() => <Redirect to='/route' />} />
<Route path='/route/' exact render={() => <Component />} />
<Route path='/route/subroute/subsubroute1/:id+' exact render={() => <Component2 />} />
<Route path='/route/subroute/subsubroute2/:id+' exact render={() => <Component3 />} />
<Route path='/route/subroute/:id+' exact render={() => <Component1/>} />
<Route path='/route/:subroute+' exact render={() => <Component4 />} />
<Route render={() => <Redirect to='/notfound' />} />
</Switch>

Categories