I am attempting to use react router to do a url like so:
example.com/admin/members/{anyid}
If this url is hit with the id it would display user info with that id.
My code:
ReactDOM.render(
<FirebaseContext.Provider value={new Firebase()}>
<BrowserRouter>
<Switch>
<Route path="/admin" render={props => <AdminLayout {...props} />} />
<Route path="/auth" render={props => <AuthLayout {...props} />} />
<Redirect from="/" to="/admin/index" />
</Switch>
</BrowserRouter>,
</FirebaseContext.Provider>,
document.getElementById("root")
);
I have attempted to do this:
<Switch>
<Route path="/admin" render={props => <AdminLayout {...props} />} />
<Route path="/auth" render={props => <AuthLayout {...props} />} />
<Route path="/admin/members/:id" component={SavedMemberForm} />
<Redirect from="/" to="/admin/index" />
</Switch>
My assumption was that /admin/members/:id would over ride any children urls in admin. This is not the case when I hit /admin/members/1234 it reads it as if I'm just going to /admin
How can I get it to achieve my desired result?
Related
So I´m currently refactoring a website, and so I do with the rrd, which was on v5 in the previous website version.
Now, that the component doesn´t exist anymore we have to work with the new component as you probably know.
I previously used framer-motion to transition in and out between the routes like so:
<Switch location={location} key={location.pathname}>
<motion.div
initial="initial"
animate="in"
exit="out"
variants={pageVariants}
transition={pageTransition}>
<Route path="/audit" component={Audit} />
<Route exact path="/smartx" component={SmartX} />
<Route path="/smartx/erc20" component={TokenGenerator} />
<Route path="/createAudit" component={PaymentStatus} />
<Route path="/faq" component={FAQ} />
<Route path="/support" component={Support} />
<Route path="/terms" component={Terms} />
<Route path="/policy" component={Policy} />
<Route path="/about" component={About} />
<Route exact path="/">
<Redirect to="/audit" />
</Route>
</motion.div>
</Switch>;
Simply replacing the Switch component with the Routes component won´t work, since you can only have Route components as childs from .
Moving the <motion.div> one layer up over the Routes component leads to only one initial fade in transition on page load.
new (not quiet working version):
<AnimatePresence>
<PageLayout>
<motion.div
initial="initial"
animate="in"
variants={pageVariants}
transition={pageTransition}>
<Routes>
<Route path="/audit" element={<Audit />} />
<Route path="/smartx" element={<SmartX />} />
<Route path="/faq" element={<FAQ />} />
<Route path="/support" element={<Support />} />
<Route path="/terms" element={<Terms />} />
<Route path="/policy" element={<Policy />} />
<Route path="/about" element={<About />} />
</Routes>
</motion.div>
</PageLayout>
</AnimatePresence>;
Framer motion animations (equalin both old and new version):
const pageVariants = {
initial: {
opacity: 0
},
in: {
opacity: 1
},
out: {
opacity: 0
}
};
const pageTransition = {
type: 'tween',
ease: 'linear',
duration: 0.5
};
Any ideas on how to achieve a transition on each route switch?
Thanks in advance and cheers!
I think your solution is close to working. Move the PageLayout component and motion.div into a layout route that uses the current path as a React key.
Example:
import { Outlet } from 'react-router-dom';
const AnimationLayout = () => {
const { pathname } = useLocation();
return (
<PageLayout>
<motion.div
key={pathname}
initial="initial"
animate="in"
variants={pageVariants}
transition={pageTransition}
>
<Outlet />
</motion.div>
</PageLayout>
);
};
...
<Routes>
<Route element={<AnimationLayout />}>
<Route path="/audit" element={<Audit />} />
<Route path="/smartx" element={<SmartX />} />
<Route path="/faq" element={<FAQ />} />
<Route path="/support" element={<Support />} />
<Route path="/terms" element={<Terms />} />
<Route path="/policy" element={<Policy />} />
<Route path="/about" element={<About />} />
<Route path="*" element={<Navigate to="/audit" replace />} />
</Route>
</Routes>
I want my react router to return component only when URL matches either of those 3 paths exactly and return an error when it doesn't. How can I shorten this?
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Table entries={posts} />} />
<Route path="/evens" element={<Table entries={posts} />} />
<Route path="/odds" element={<Table entries={posts} />} />
<Route ??? element={<ErrorPage />} />
</Routes>
</BrowserRouter>
);
RRDv6 routes take only a string path prop. If you need to render the same component on multiple paths you need to render a Route for each.
To make the code a little more DRY you could try mapping the routes from an array of paths.
Example:
return (
<BrowserRouter>
<Routes>
{["/", "/evens", "/odds"].map(path => (
<Route
key={path}
path={path}
element={<Table entries={posts} />}
/>
)}
<Route path="*" element={<ErrorPage />} />
</Routes>
</BrowserRouter>
);
Now whether or not this is more readable or maintainable is likely up for debate/opinion. It is less repetitive though.
I'm working on a React app that is using React Router 4. All of my routes are working great, however, if I go to a route that is not on the list I am not getting my 404 page. Any idea what I'm missing?
I'm using React 16 and React Router 4. This is for a sample app like Indeed.
export default function App() {
const companyRoutes = () => (
<Main>
<Route exact path="/companies/new" component={NewCompanyPage} />
<SubNav>
<PageBody companyPages>
<Switch>
<Route exact path="/companies" component={CompanyPage} />
<Route path="/companies/:companyId/edit" component={EditCompanyPage} />
<Route path="/companies/:companyId/jobs/:jobId/edit" component={EditJobPage} />
<Route path="/companies/:companyId/jobs/new" component={NewJobPage} />
<Route path="/companies/:companyId/jobs" component={CompanyJobsPage} />
<Route path="/companies/:companyId/locations" component={CompanyLocationsPage} />
<Route path="/companies/:companyId/recruiters" component={CompanyRecruitersPage} />
<Route path="/companies/:companyId/settings" component={CompanySettingsPage} />
<Route path="/companies/:companyId/applicants" component={CompanyApplicantsPage} />
</Switch>
</PageBody>
</SubNav>
</Main>
)
const jobRoutes = () => (
<Main>
<PageBody>
<Switch>
<Route exact path="/jobs" component={JobsPage} />
<Route path="/jobs/:jobId" component={JobPage} />
<Route path="/jobs/:jobId/apply" component={NewApplicationPage} />
</Switch>
</PageBody>
</Main>
)
const profileRoutes = () => (
<Main>
<SubNav>
<PageBody>
<Switch>
<Route exact path="/profiles" component={ProfilePage} />
<Route path="/profiles/:profileId/resume" component={ResumePage} />
<Route path="/profiles/:profileId/edit" component={EditProfilePage} />
<Route path="/profiles/:profileId/applications" component={ApplicationsPage} />
<Route path="/profiles/:profileId/settings" component={ProfileSettingsPage} />
</Switch>
</PageBody>
</SubNav>
</Main>
)
const loginRoutes = () => (
<LoginMain>
<Switch>
<Route exact path="/login" component={LoginPage} />
<Route exact path="/sign_up" component={LoginPage} />
</Switch>
</LoginMain>
)
const MainRoutes = () => (
<div>
<Route path="/companies" component={companyRoutes} />
<Route path="/jobs" component={jobRoutes} />
<Route path="/login" component={loginRoutes} />
<Route path="/profiles" component={profileRoutes} />
</div>
)
return (
<BrowserRouter>
<div>
<Route path="/" component={MainRoutes} />
<Route path="/404" component={NotFoundPage} />
</div>
</BrowserRouter>
)
}
[UPDATE]: Here you will find a proper, better tested example.
Not tested but try:
return (
<BrowserRouter>
<Switch>
<Route path="/" component={MainRoutes} />
<Route component={NotFoundPage} />
</Switch>
</BrowserRouter>
)
The idea is that inside a Switch, the router will try every route from the first one to the last one until it finds a corresponding path.
By having <Route component={NotFoundPage} /> at the very bottom of your routing, with no path specified, it will act as a wildcard, catching all unmatched urls.
I'm trying to use ReactCSSTransitionGroup for react router transitions and have followed the examples from the documentation but I get the following Uncaught TypeError: Cannot read property 'key' of undefined
What am I doing wrong? Why is location undefined?
render() {
const {categories, language, location, reviews, subCategories} = this.props
return(
<Wrap>
<Router>
<ScrollToTop>
<Header categories={categories} language={language} />
<Wrap>
<TransitionGroup>
<CSSTransition
key={location.key}
timeout={{ enter: 300, exit: 300 }}
classNames={'fade'}
>
<Switch location={location}>
<Route exact path="/" render={props => <Home categories={categories} subCategories={subCategories} reviews={reviews} language={language} {...props} />} />
<Route exact path="/:catId" render={props => <ReviewsFilteredByCategory categories={categories} subCategories={subCategories} language={language} {...props} />} />
<Route exact path="/:catId/:slug" render={props => <ReviewsTop10 categories={categories} subCategories={subCategories} reviews={reviews} language={language} {...props} />} />
</Switch>
</CSSTransition>
</TransitionGroup>
</Wrap>
<Footer />
</ScrollToTop>
</Router>
</Wrap>
)
}
}
function getFluxComponent(){
return <App flux={flux} />
}
render((
<Router history={history}>
<Route path="/" compopent={getFluxComponent()} >
<Route path="login" component={Login} />
<Route path="logout" component={Logout} />
<Route path="about" component={About} />
<Route path="watch" component={Watch} onEnter={requireAuth} />
</Route>
</Router>
), document.getElementById('example'))
I wanted to pass App component with flux property.
but I cannot set.
How to set flux property to App component.