React Router with Context - javascript

I'm wrapping some private routes with a context, but for some reason it doesn't move to the next route in the switch.
export const Routes = () => (
<Switch>
<Route exact path="/" component={Home} />
<Route path="/seller/:userName" component={userProfile} />
<Route path="/allproducts" component={AllProducts} />
<Route path="/privacy" component={Privacy} />
<Route path="/terms" component={Terms} />
<Route path="/contact" component={Contact} />
<Route path="/about" component={About} />
<Route path="/learnmore" component={LearnMore} />
<Route path="/faq" component={FAQ} />
<PublicRoute path="/login" component={Login} />
<PublicRoute path="/signup" component={SignUp} />
<PublicRoute path="/reset" component={ForgotPassword} />
<PublicRoute path="/resetToken" component={ForgotPasswordToken} />
<PrivateRoute exact path="/userprofile" component={UserDashboard} />
<PrivateRoute exact path="/submitplate" />
// This works but doesn't allow the router to move to the next potential route.
<BasketProvider>
<PrivateRoute exact path="/checkout" component={Checkout} />
</BasketProvider>
// This never gets reached.
<Route component={NoMatchPage} />
</Switch>
);
Just wondering if theres a better way to go around this? Is this bad practice?

Does it work if you do this?
<PrivateRoute exact path="/checkout" component={() => (
<BasketProvider>
<Checkout />
</BasketProvider>
)} />

Related

How can I arrange my Routes on the App component

I have various routes and I also have some data from context api that I want to pass to certain routes, excluding some. So,
There is the <UserContext.Provider> that should be wrapped inside all the routes.
There is also the <Route element={<PrivateRoute />}> that sould be wrapped inside most of the routes because it should be checking the authenticated user.
And then there are components like <FruitsData> and <WeatherData> that I should only use to wrap <Route path="training" element={<Training />} /> which is inside <Route element={<PrivateRoute />}> and <UserContext.Provider>
So, my question. How can I wrap the component mentioned in no.3 the right way without having to wrap it around all the other components like I have done below?
<UserContext.Provider value={user}>
<WeatherData>
<FruitsData>
<Routes>
<Route element={<PrivateRoute />}>
<Route path="/" element={<Dashboard />} />
<Route path="/test" element={<TestPage />} />
<Route path="training" element={<Training />} />
<Route path="fruit-details/:fruitId" element={<FruitDetails />} />
<Route path="my-farm" element={<MyFarmList />} />
<Route path="add-farm" element={<AddFarm />} />
<Route path="farm-details" element={<FarmDetails />} />
<Route path="add-post" element={<AddPost />} />
<Route path="post-details/:postId" element={<PostDetails />} />
<Route path="infestation-details/:infestationId" element={<InfestationDetails />} />
<Route path="farm-details/:username/:farmId" element={<FarmDetails />} />
<Route path="farm-details/:username/:farmId/fruits" element={<FarmFruits />} />
<Route path="area" element={<Area />} />
<Route path="shop" element={<Shop />} />
<Route path="packages" element={<Packages />} />
<Route path="seedlings" element={<Seedlings />} />
<Route path="profile" element={<Profile />} />
<Route path="product-details/:seedlingId" element={<ProductDetails />} />
<Route path="pricing" element={<Pricing />} />
<Route path="community" element={<Community />} />
<Route path="complete-profile" element={<CompleteProfile />} />
</Route>
<Route path="admin/" element={<AdminPrivateRoute />}>
<Route path="home" element={<Home />} />
<Route path="farmers" element={<Farmers />} />
<Route path="farms" element={<Farms />} />
</Route>
</Routes>
</FruitsData>
</WeatherData>
</UserContext.Provider>
Thank you
I don't see any overt issue with the way all the context providers wrap the entirety of the routes, but if you are trying to limit the scope of any specific provider then the solution here is to have them render an Outlet component instead of the children prop and render them as layout routes.
Example:
const UserLayout = () => {
... logic/state/etc ...
return (
<UserContext.Provider value={user}>
<Outlet />
</UserContext.Provider>
);
};
const FruitesWeatherLayout = () => {
... logic/state/etc ...
return (
<WeatherData>
<FruitsData>
<Outlet />
</FruitsData>
</WeatherData>
);
};
...
<Routes>
<Route element={<UserLayout />}> // <-- layout route
<Route element={<PrivateRoute />}>
<Route path="/" element={<Dashboard />} />
<Route path="/test" element={<TestPage />} />
<Route element={<FruitesWeatherLayout />}> // <-- layout route
<Route path="training" element={<Training />} />
</Route>
<Route path="fruit-details/:fruitId" element={<FruitDetails />} />
<Route path="my-farm" element={<MyFarmList />} />
<Route path="add-farm" element={<AddFarm />} />
<Route path="farm-details" element={<FarmDetails />} />
<Route path="add-post" element={<AddPost />} />
<Route path="post-details/:postId" element={<PostDetails />} />
<Route path="infestation-details/:infestationId" element={<InfestationDetails />} />
<Route path="farm-details/:username/:farmId" element={<FarmDetails />} />
<Route path="farm-details/:username/:farmId/fruits" element={<FarmFruits />} />
<Route path="area" element={<Area />} />
<Route path="shop" element={<Shop />} />
<Route path="packages" element={<Packages />} />
<Route path="seedlings" element={<Seedlings />} />
<Route path="profile" element={<Profile />} />
<Route path="product-details/:seedlingId" element={<ProductDetails />} />
<Route path="pricing" element={<Pricing />} />
<Route path="community" element={<Community />} />
<Route path="complete-profile" element={<CompleteProfile />} />
</Route>
<Route path="admin/" element={<AdminPrivateRoute />}>
<Route path="home" element={<Home />} />
<Route path="farmers" element={<Farmers />} />
<Route path="farms" element={<Farms />} />
</Route>
</Route>
</Routes>

How can React-Router-Dom v6 properly distribute internal routers among components?

There is routing at the top level with internal routing, the question arose to add routing inside components such as ProductsPage, ElementsPage, etc.
<BrowserRouter>
<Routes>
<Route path='/' element={<PageLayout />}>
<Route path='marketplace'>
<Route path='products' element={<ProductsPage />} />
<Route path='constituents' element={<ElementsPage />} />
<Route path='resources' element={<ResourcesPage />} />
<Route path='shopping' element={<ShoppingPage />} />
</Route>
<Route path='resource-center'>
<Route path='planner' element={<>планирование</>} />
<Route path='resources' element={<>resources</>} />
</Route>
<Route path='*' element={<>Страница не найдена 404</>} />
</Route>
</Routes>
</BrowserRouter>
The question is how to do this in version 6. Because before version five, you could easily throw a switch into a component a la ProductsPage and specify routes in the switch
You can name all pages explicitly.
<BrowserRouter>
<Routes>
<Route path='/' element={<PageLayout />} />
<Route path='/marketplace/products' element={<ProductsPage />} />
<Route path='/marketplace/constituents' element={<ElementsPage />} />
<Route path='/marketplace/resources' element={<ResourcesPage />} />
<Route path='/marketplace/shopping' element={<ShoppingPage />} />
<Route path='/resource-center/planner' element={<планирование />} />
<Route path='/resource-centerresources' element={<resources/>} />
<Route path='*' element={<Страница не найдена 404/>} />
</Routes>
</BrowserRouter>

How to hide my NavigationBar Component when on certain paths

Been looking around for a fix, can't seem to find something that works here, I've tried using the match tag to match it to a certain page, but it isn't working correctly. pretty lost here.
return (
<React.Fragment>
<Router>
{/* <NavigationBar /> PLACE PREFERRED NAVIGATION IN LINE BELOW */}
<NavigationBar />
<AuthProvider>
<Switch>
<Route exact path="/" component={Login} />
<Route exact path="/signup" component={Signup} />
<PrivateRoute exact path="/home" component={Home} />
<PrivateRoute exact path="/map" component={MapPage} />
<PrivateRoute exact path="/profile" component={Profile} />
<PrivateRoute exact path="/feedback" component={Feedback} />
<PrivateRoute exact path="/about" component={About} />
<PrivateRoute exact path="/resources" component={Resources} />
<PrivateRoute exact path="/academic" component={Academic} />
<PrivateRoute exact path="/career" component={Career} />
<PrivateRoute exact path="/financial" component={Financial} />
<PrivateRoute exact path="/physical" component={Physical} />
<PrivateRoute exact path="/psycho" component={Psycho} />
<PrivateRoute exact path="/social" component={Social} />
<PrivateRoute exact path="/spiritual" component={Spiritual} />
<PrivateRoute exact path="/badges" component={Badges} />
<Route exact path="/404" component={NotFoundPage} />
<Route exact path="/underConstruction" component={pageUnderConstruction} />
<Redirect to="/404" />
</Switch>
</AuthProvider>
</Router>
</React.Fragment>
)
I think you can use the useLocation hook by react router Dom.
You would import the hook: import { useLocation } from 'react-router-dom';
const location = useLocation()
Then in the component you want style={{ display: location.pathname === '/' ? 'none' : 'block' }}
Updated
Here is solution:
import { createBrowserHistory } from "history";
const history = createBrowserHistory()
{allowedRoutesNavbarToShow.includes(history.location.pathname) && (
<Navbar />
)}
To update the browser history do following steps:
<Route path="/" exact component={Something} />
Something.js
export default function Something(props) {
function handleClick() {
props.history.push("/somewhere");
}
return (
<button onClick={handleClick}>Go to Somewhere</button>
);
}
Visit to see full code and live working solution:
Codesandbox
Happy coding :)

React - How to forward requests to routes that are not listed in the Router to a NotFound (404) component?

Consider the Router :
<Router>
<Fragment>
<Navbar />
{/* <Landing /> */}
<Route exact path="/" component={Landing} />
<section className="containerSpecial">
<Alert />
<Switch>
<Route exact path="/register" component={Register} />
<Route exact path="/forgot-my-password" component={ForgotMyPassword}/>{" "}
<Route exact path="/reset-password" component={ResetPassword} />
<Route exact path="/login" component={Login} />
<PrivateRoute exact path="/dashboard" component={Dashboard} />{" "}
... More PrivateRoutes
// Another route that forwards to "NotFound" Component
</Switch>
</section>
</Fragment>
</Router>
When the user hits a url like http://localhost:3000/dashboard or any other url from the
listed above , is being forward to the corresponding component.
However when users hit http://localhost:3000/ddlksajldsajk or http://localhost:3000/dashboard1
nothing is being rendered.
How can I forward urls that are not listed to a NotFound component ?
just add <Route component={NoMatch} /> :
<Router>
<Fragment>
<Navbar />
{/* <Landing /> */}
<Route exact path="/" component={Landing} />
<section className="containerSpecial">
<Alert />
<Switch>
<Route exact path="/register" component={Register} />
<Route exact path="/forgot-my-password" component={ForgotMyPassword}/>{" "}
<Route exact path="/reset-password" component={ResetPassword} />
<Route exact path="/login" component={Login} />
<PrivateRoute exact path="/dashboard" component={Dashboard} />{" "}
... More PrivateRoutes
// Another route that forwards to "NotFound" Component
<Route component={NotFound} />
</Switch>
</section>
</Fragment>
</Router>
see react router handling 404 pages
Add a new route like this as the very last route:
<Route path='/' component={my404Component} />
Notice it does not have exact. Anything that hasn't been matched will match with it and send them to the 404.

reactjs - 404 page - and language param missing handling issues

I am new to reactjs - working on a site with a language switch I am trying to create an error component to use as a 404 page - but also trying to see how to configure/automatically switch the site to use a default language if the parameter is not defined or to set the error path to still listen out for the lang param.
router.js currently looks like this
<Switch>
<Route exact path='/' render={() => (<Redirect to='/de/dienstleistungen/geistiges-eigentum' />)} />
<Route path='/:langURL/services' component={Services} />
<Route path='/:langURL/dienstleistungen' component={Services} />
<Route path='/services' component={Services} />
<Route path='/:langURL/how-it-works' component={HowItWorks} />
<Route path='/:langURL/anleitung' component={HowItWorks} />
<Route path='/:langURL/features' component={Features} />
<Route path='/:langURL/funktionen' component={Features} />
<Route path='/:langURL/beliebte-projekte' component={BundleDetails} />
<Route path='/:langURL/popular-projects' component={BundleDetails} />
<Route component={Error} />
</Switch>
I think you're saying the problem is that you want the user to be able to not provide the language parameter in the URL? And that right now if they don't provide it they're thrown into the Error component? You can make that parameter optional by using :langURL?:
<Switch>
<Route exact path='/' render={() => (<Redirect to='/de/dienstleistungen/geistiges-eigentum' />)} />
<Route path='/:langURL?/services' component={Services} />
<Route path='/:langURL?/dienstleistungen' component={Services} />
<Route path='/services' component={Services} />
<Route path='/:langURL?/how-it-works' component={HowItWorks} />
<Route path='/:langURL?/anleitung' component={HowItWorks} />
<Route path='/:langURL?/features' component={Features} />
<Route path='/:langURL?/funktionen' component={Features} />
<Route path='/:langURL?/beliebte-projekte' component={BundleDetails} />
<Route path='/:langURL?/popular-projects' component={BundleDetails} />
<Route component={Error} />
</Switch>

Categories

Resources