how to get params using react router dom v5.0.1 - javascript

how to get params using react router dom v5.0.1 before I could get parameters, but now I can't get them, what's the problem?
<BrowserRouter>
<Route path='/' exact component={Login} />
<Route path='/register' component={Register} />
<Route path='/home' component={Home} />
<Route path='/all/merchant' component={AllMerchant} />
<Route path='/detail/merchant/:id_merchant' exact component={DetailMerchant} />
<Route path='/detail/merchant/promo/:id_merchant' component={MerchantByPromo} />
<Route path='/promo/voucher/by/merchant/' component={MerchantByPromoDetail} />
<Route path='/all/category' component={Category} />
<Route path='/category/id/:category_id' component={CategoryById} render = {props => <CategoryById {...props} key={this.props.match.params} /> }/>
<Route path='/promo/grid/view' component={PromoGridView} />
{/* params not found */}
<Route path='/promo/grid/view/by/category/:category_id' component={AllPromoGridView} />
<Route path='/detail/promo/:voucher_id/category_id/:category_id' component={PromoGridViewDetail} />
{/* params not found */}
<Route path='/account' component={Account} />
</BrowserRouter>

According to the react-router doc, it should be accessible in your Component via the props match:
Example:
// the route
<Route path="/:id" component={Child} />
/*
...
*/
//the component
function Child({ match }) {
return (
<div>
<h3>ID: {match.params.id}</h3>
</div>
);
}

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>

Redirect to specific page if localstorage value not found in react

I am using reactjs.
I have multiple following routes in my index.js file
<BrowserRouter>
<App>
<Switch>
<Route exact path="/" component={Home} />
<Route exact path="/Login" component={SignIn} />
<Route exact path="/Sign-up" component={SignUp} />
<Route exact path="/Orders" component={Orders} />
<Route exact path="/Category" component={Category} />
<Route exact path="/Shops" component={Shops} />
</Switch>
</App>
</BrowserRouter>
initially when user goes to base URL suppose
Http://localhost:3000
he should be redirected to
Http://localhost:3000/Shops page if value of localstorage item is null
and also if user tries to visit other pages he should be redirected to the /Shops page.
One way of doing this is using HOC but further i'll be adding auth soo there i'll have to wrap the component in route with HOC like this
<Route exact path="/Orders" component={AuthGuard(Orders)} />
I dont know whether I can do like this
<Route exact path="/Orders" component={AuthGuard, ShopGuard(Orders)} />
soo how can i achieve this without using HOC or how can I wrap 2 HOC for a single component.
Thanks.
function HandleRedirection() {
const RedirectToShop = ({ component: Component, ...rest }) => {
return (
<Route
{...rest}
render={(props) =>
localStorage.getItem('user') ? (
<App>
<Component {...props} />
</App>
) : (
<Redirect to="/shop" />
)}
/>
);
};
return (
<BrowserRouter basename={`/`}>
<Switch>
<Route path={`/shop`} component={Shops} />
<RedirectToShop exact path={`/login`} component={Signin} />
<RedirectToShop exact path={`/order`} component={Order} />
<RedirectToShop exact path={`/category`} component={Category} />
<Redirect to="/shop" />
</Switch>
</BrowserRouter>
);
}
Create a custom Route component that can check localStorage and redirect to "/shop" if condition is (or isn't?) met.
const ShopGuardRoute = ({ component: Component, ...props }) => (
<Route
{...props}
render={routeProps => {
const item = localStorage.getItem("key");
// Do all your conditional tests here
return item !== null ? (
<Component {...routeProps} />
) : (
<Redirect to="/shop" />
);
}}
/>
);
Usage
<BrowserRouter>
<App>
<Switch>
<ShopGuardRoute path="/Login" component={SignIn} />
<ShopGuardRoute path="/Sign-up" component={SignUp} />
<ShopGuardRoute path="/Orders" component={Orders} />
<ShopGuardRoute path="/Category" component={Category} />
<Route path="/Shops" component={Shops} />
<Route path="/" component={Home} />
</Switch>
</App>
</BrowserRouter>
If you plan on adding an authentication check then auth-workflow may help.
I think you can just do something like this on all the required pages if(condition // your local storage null check) { history.push(/yourPath, dataIfAny); }

How to make "404 - Not Found" page/route with react-router?

How do I add 404 - Not Found page in React with React-Router?
Here's my attempt:
// routes.tsx
export const routes = [
{
path: '/students',
render: (props: any) => <List {...props} title={`Students`} />,
},
{
path: '/teachers',
render: (props: any) => <List {...props} title={`Teachers`} />,
},
]
// App.tsx
import { routes } from './routes'
function App() {
const routeComponents = routes.map(({ path, render }, key) => (
<Route exact path={path} render={render} key={key} />
))
return (
<ThemeProvider theme={theme}>
<CSSReset />
<Suspense fallback={<Loader />}>
<Router>
<Switch>
<Route exact path="/" component={Signin} />
<Route path="/signin" component={Signin} />
<Layout>{routeComponents}</Layout>
{/* <Route component={NotFound} /> */}
<Route path="*" component={NotFound} />
</Switch>
</Router>
</Suspense>
</ThemeProvider>
)
}
export default App
But I can't see my custom "404 - Not Found" page when I go to 'http://localhost:3000/nothing', but <Layout /> component.
What I am doing wrong?
Stack: TypeScript, React#v16.13.1, react-router-dom#v5.1.2
404 Page on react does not need to have a path as it needs to be a page rendered when roue is not found between the paths of the pages you already have. It should work this way:
<Switch>
<Route exact path="/" component={Signin} />
<Route path="/signin" component={Signin} />
{routeComponents()}
<Route component={NotFound} />
</Switch>
Left blank path="". It will render 404 page.
see -
<Route path="" component={PageNotFound} />
<Route exact path="/" component={Signin} />
<Route path="/signin" component={Signin} />
This can fix
https://stackoverflow.com/a/64651959/16361679
return (
<ThemeProvider theme={theme}>
<CSSReset />
<Suspense fallback={<Loader />}>
<Router>
<Switch>
<Route exact path="/" component={Signin} />
<Route path="/signin" component={Signin} />
<Layout>
<Switch>
{routeComponents}
<Route path="*" component={NotFound} />
<Switch>
</Layout>
</Switch>
</Router>
</Suspense>
</ThemeProvider>
)

React nested routing problem (cannot displayed the child component)

I am new to react development. And I want to implement the routing mechanism in my page.
For example, there's component contains routes with the <Home /> and <Login /> component.
function App() {
return (
<div className="App">
<Switch>
<Route exact path="/home">
<Home />
</Route>
<Route path="/login">
<Login />
</Route>
</Switch>
</div>
);
}
The <Home /> component contains a <Navbar /> and a <Switch /> with two <Route />:
Home.js
function Home() {
return (
<div>
<Navbar />
<div>
<Switch>
<Route exact path={`/home`}>
<Menu />
</Route>
<Route path={`/home/temperature`}>
<div>temperature</div>
</Route>
</Switch>
</div>
</div>
)
}
However, I defined the <Link /> in the <Menu /> component as below:
function Menu() {
return (
<div>
<li>
<Link to={`/home/temperature`}>temperature child page</Link>
</li>
</div>
)
}
Originally, the page would displayed the <Home /> component with <Menu /> and <div> temperature </div>
I expected that when I clicked the link (<Link to={/home/temperature}>temperature child page</Link>) then it would replace the <Menu /> component with the only the <div>temperature</div> (Dispalyed the <Navbar/> and <div>temperature</div>, but it could not display anything.
How should I correct it?
Solution:
I finally figure out why I cannot get child component in my js script.
Firstly, I need to wrap the <Switch> with <Router> in <App> component.
Then, by reference this , I realized that I should not specify the exact in <Route path="/home"> to make sure that the nested route can work as well.
function App() {
return (
<div className="App">
<Router>
<div>
<Switch>
<Route path="/home">
<Home />
</Route>
<Route path="/login">
<Login />
</Route>
</Switch>
</div>
</Router>
</div>
);
}
simple routing
<Router>
<Switch>
<Route path={"/home"} exact component={Home} />
</Switch>
</Router>
nested routing
<Router>
<Switch>
<Route path={"/home"} exact component={Home}
<Rout path={"/temperature"} exact component={Temperature} />
</Route>
</Switch>
</Router>
`

How to put a div inside a Switch with React Router?

I have an APP using React and Redux, and I wanted to load a NotFound component when the user enters an invalid route. I found online a way to solve that problem, that is by putting all the routes inside a switch, including the NotFound component.
The problem is that, in my app, I can't put all my routes inside a Switch because There is a single component that needs to be stretched to the entire page, while all the other components need to be inside a "container". The way I have it below (see the code), the NotFound component works for all cases, except when I'm on the "landing" component route (where the NotFound component always displays).
I tried to put the landing component inside the Switch with the "container" div but the app crashes.
Is there any way to solve this? (keeping the landing component out of the container, and the other components inside)
class App extends Component {
render() {
return (
<Provider store={store}>
<Router>
<div className="App">
<Navbar />
<Route exact path="/" component={Landing} />
<div className="container">
<Switch>
<Route exact path="/register" component={Register} />
<Route exact path="/login" component={Login} />
<Route exact path="/profiles" component={Profiles} />
<Route exact path="/profile/:handle" component={Profile} />
<PrivateRoute exact path="/dashboard" component={Dashboard} />
<PrivateRoute
exact
path="/create-profile"
component={CreateProfile}
/>
<PrivateRoute
exact
path="/edit-profile"
component={EditProfile}
/>
<PrivateRoute
exact
path="/add-experience"
component={AddExperience}
/>
<PrivateRoute
exact
path="/add-education"
component={AddEducation}
/>
<PrivateRoute
exact
path="/edit-education/:id"
component={EditEducation}
/>
<PrivateRoute exact path="/feed" component={Posts} />
<PrivateRoute exact path="/post/:id" component={Post} />
<Route component={NotFound}/>
</Switch>
</div>
<Footer />
</div>
</Router>
</Provider>
);
}
}
You can make a separate router for all other components except landing page.
// App.js
import NonLandingPages from './NonLandingPages';
class App extends Component {
render() {
return (
<Provider store={store}>
<Router>
<div className="App">
<Navbar />
<Switch>
<Route exact path="/" component={Landing} />
<Route component={NonLandingPages}/>
</Switch>
<Footer />
</div>
</Router>
</Provider>
);
}
}
Separate router for all other pages
// NonLandingPages.js
class NonLandingPages extends Component {
render() {
return (
<div className="container">
<Switch>
<Route exact path="/register" component={Register} />
<Route exact path="/login" component={Login} />
<Route exact path="/profiles" component={Profiles} />
<Route exact path="/profile/:handle" component={Profile} />
<PrivateRoute exact path="/dashboard" component={Dashboard} />
<PrivateRoute
exact
path="/create-profile"
component={CreateProfile}
/>
<PrivateRoute
exact
path="/edit-profile"
component={EditProfile}
/>
<PrivateRoute
exact
path="/add-experience"
component={AddExperience}
/>
<PrivateRoute
exact
path="/add-education"
component={AddEducation}
/>
<PrivateRoute
exact
path="/edit-education/:id"
component={EditEducation}
/>
<PrivateRoute exact path="/feed" component={Posts} />
<PrivateRoute exact path="/post/:id" component={Post} />
<Route component={NotFound}/>
</Switch>
</div>
);
}
}

Categories