Realize router transitions for solely one component - javascript

I have the following routes. I want only one route to be transitioned, namely /about. No other route shall have a routing transition. The component About shall be animated in from the bottom to top overlapping the previous component.
How can I ensure only the given route to be transitioned? Additionally the component CartHolder shall not be removed on route change - as you can see in the code below, I want it to be displayed on two different paths.
How can I realize such behavior? Is react-router-transition the way to go? - If so, how can I consider the conditions above?
const history = createBrowserHistory();
function App() {
return (
<div className="App">
<Router history={history}>
<ScrollToTop>
<Header/>
{projects ?
<div>
<Route path="/project/:name" component={() => <Project carts={projects}/>}/>
<Route path="/about" component={About}/>
<div className="hs">
<Route path={["/", "/project/:name"]} exact
component={() => <CartHolder carts={projects}/>}/>
</div>
<div className="hs-mobile">
<Route path="/" exact component={() => <CartHolderMobile carts={projects}/>}/>
</div>
</div>
: <div className="black-overlay"/>}
</ScrollToTop>
</Router>
</div>
)
}

Related

A route is not covered in layout component, but still renders layout in React

I'm having to trouble making a route without layout component. Please check my code first.
// App.js
const App = () => {
return (
<div className={styles.container}>
<Header />
<main>
<QuizBoxContainer>
<Routes>
<Route path='/' element={<QuizSelect />} />
<Route path='quiz-for/:language' element={<QuizCard />} />
<Route path='result' element={<ResultPage />} />
</Routes>
</QuizBoxContainer>
<Routes>
<Route path='wrong-answer' element={<WrongAnswer />} />
</Routes>
</main>
</div>
)
}
In the code, <QuizBoxContainer> is the layout component.
What I was trying to do is making another path,
<Routes>
<Route path='wrong-answer' element={<WrongAnswer />} />
</Routes>
outside of <QuizBoxContainer> so I can use another layout on this component.
However, when I go to WrongAnswer,
It still renders.
What is wrong with my code, and how can I solve it?
Issue
The is because the QuizBoxContainer layout wrapper component is not rendered on any route, it's always rendered.
Solution
Move QuizBoxContainer into a layout route. You'll need to update QuizBoxContainer so it renders an Outlet component instead of the children prop.
Example:
import { Outlet } from 'react-router-dom';
const QuizBoxContainer = () => {
...
return (
... quiz container layout/styling ...
<Outlet /> // <-- nested routes render content here
...
);
};
Render QuizBoxContainer on a layout route wrapping the routes you want to render within it, render the wrong answer route outside the layout route.
const App = () => {
return (
<div className={styles.container}>
<Header />
<main>
<Routes>
<Route element={<QuizBoxContainer />}>
<Route path='/' element={<QuizSelect />} />
<Route path='quiz-for/:language' element={<QuizCard />} />
<Route path='result' element={<ResultPage />} />
</Route>
<Route path='wrong-answer' element={<WrongAnswer />} />
</Routes>
</main>
</div>
)
}

React nested route page not rendering properly as expected

I created this react component which has some nested routes. The problem is that the nested page component is either not rendering at all despite the URL changes or just returns a blank page.
I tried the suggestions from other posts like adding/removing exact in the parent route, but it's still not working.
Below are my codes:
// the parent component
<div className="App">
<Router>
<Navbar />
<Switch>
<Route exact path="/" render={() => <MyPage accessToken={accessToken} />}/>
<Route path="/editing/:playlistId" render={(props) =>
<EditingPlaylist {...props} accessToken={accessToken} />} />
</Switch>
</Router>
</div>
//the child component EditingPlaylist
render() {
const { pathname } = this.props.location;
return (
<div className="editing">
<Switch>
<Route exact path={pathname} render={() =>
<Searchbar accessToken={this.props.accessToken} />} />
<Route path={`${pathname}/test`} component={<p>Test</p>} />
<Route path={`${pathname}/album/:albumId`} render={
(props) => <AlbumPage {...props} accessToken={this.state.accessToken} />} />
<Route path={`${pathname}/artist/:artistId`} render={
(props) => <ArtistProfile {...props} accessToken={this.state.accessToken} />} />
</Switch>
</div>)
}
export default withRouter(EditingPlaylist);
Use url and path:
const { url, path } = this.props.match
to defined nested routes.
So, in nested routes:
<Switch>
<Route
exact
path={path} // HERE
render={() => <Searchbar accessToken={this.props.accessToken} />}
/>
...
</Switch>
There is a difference between url and path:
url: It is what is visible in the browser. e.g. /editing/123. This should be used in when redirecting via Link or history.push
path: It is what matched by the Route. e.g. /editing/:playlistId. This should be used when defining (nested) paths using Route.
From docs:
path - (string) The path pattern used to match. Useful for building nested <Route>s
url - (string) The matched portion of the URL. Useful for building nested <Link>s

How to prioritize the route in React?

I'm making React app, and I have some Routers.
const App = () => {
return (
<div>
<Header/>
<div>
<Route path="/LogIn" render={() => <LogIn />} />
<Route path="/Shop" render={() => <GoodsContainer />} />
<Route path="/Delivery" render ={() => <Delivery />} />
</div>
<Footer />
</div>
)
}
When I open my page for the first time, there're only Headercomponent and Footer component, and It's logically because the url has not contain pathes which I have set to the Routes.
So, my question is how to show always , for example the Route <Route path="/Shop" render={() => <GoodsContainer />} /> when the user open the site.
Redirect isn't my solution.
path prop could either be a string or an array of strings. You can define multiple paths for GoodsContainer component using an array of strings as a value for path prop
<Route path={["/", "/Shop"]} render={() => <GoodsContainer />} />
and don't forget to either use exact prop on Route component or wrap all Route component with Switch component otherwise / path will match all other routes.
You can check #Yousef answer for this , Also if you arent passing any props, then do this instead. Don't forget to give the exact
<Route path={["/", "/Shop"]} exact render={GoodsContainer} />
But if you are passing then do this
<Route path={["/", "/Shop"]} exact render={(props)=> <GoodsContainer {...props} />} />

Is there a best practice way to hide component using react router?

To hide the navbar on the home component I am doing the following
const NavbarComponent = (props) => {
console.log(props);
if (props.match.path === '/') {
return null;
} else
return (
it works fine, I need to have access to the router so I can send people to locations dependant on the props object , is there a better way to do it such that I have all router logic in the same place?
this is the current state of my router
return (
<div>
<Router>
<Route component={Navbar} />
<Switch>
<Route exact path="/" component={Home} />
<Route exact path="/api/:city/electronics" component={Electronics} />
<Route exact path="/api/:city/labour" component={Labour} />
<Route exact path="/api/posts/item/:id" component={ItemDetails} />
<Route exact path="/create/:city/:category" component={CreatePost} />
</Switch>
</Router>
</div>
);
thanks for your time.
I'm not sure I understand why your NavBar component is in it's own Route. Any components contained within the Router have access to the entire Router api, including Link - they do not need to be a Route to do so.
I would suggest wrapping all the Routes that include the NavBar with that component. The Routes will then be displayed as children of the Navbar component.
Here is a simplified example:
// App.js
return (
<div>
<Router>
<Switch>
<Route exact path="/" component={Home} />
<NavBar>
<Route exact path="/electronics" component={Electronics} />
<Route exact path="/labour" component={Labour} />
</NavBar>
</Switch>
</Router>
</div>
);
//NavBar.js
return (
<>
<div>
<Link to="/electronics">Electronics</Link>
<Link to="/labour">Labour</Link>
</div>
<div>{props.children}</div>
</>
);
codesandbox

Nested react routes with different page layouts

I'm having two issues with my code:
Number One:
My whole application seems to work fine, I can access all my routes when I first load my web app. My app consists of a Landing Page with its navbar that has a login button that takes me straight to my application's home page (haven't added authentication yet). This home page has a navbar that is different from the one on the landing page. The navbar items are (home, about and LandingPage). My App.js has routes to the landing page component, the home page which is the Gitapp component, and a PageNotFound component. The Gitapp component contains routes to the about page and other components. If i happen to reload the page while i'm on one of the routes on App.js (first-level routes) it reloads fine. However, if I'm on the routes (second-level routes) that exist on my Gitapp component, like the route for the about page and i reload the page, I get the PageNotFound Component.
Number Two:
My second Navbar has a logout button that should take me back to the landing page. For some Reason I can't get it to work because If I add the route to the landing page in my Gitapp component, React will try to display the landing page underneath the Home page.
This is App.js:
const App = () => {
return (
<Fragment>
<Router>
<Switch>
<Route exact path='/' component={LandingPage} />
<Route exact path='/gitapp' component={GitApp} />
<Route component={PageNotFound} />
</Switch>
</Router>
</Fragment>
);
};
This is LandingPage.js:
const LandingPage = () => {
return (
<div>
<NavbarLanding />
<SideNavBar />
<LandingSection1 />
<LandingSection2 />
<LandingSection3 />
<Route exact path='/gitapp' component={GitApp} />
</div>
);
};
This is Gitapp.js:
const GitApp = ({ match }) => {
return (
<GithubState>
<Router>
<div style={containerStyling}>
<Navbar />
<Switch>
<Route exact path={match.url} component={Home} />
<Route
exact
path={`${match.url}/user/:login`}
component={UserProfile}
/>
<Route exact path={`${match.url}/about`} component={About} />
</Switch>
<Footer />
</div>
</Router>
</GithubState>
);
};
const containerStyling = {
minHeight: '100vh',
overflow: 'hidden',
display: 'block',
position: 'relative',
paddingBottom: '70px'
};
I have resolved both issues! I had to get rid of the word exact in the Gitapp route defined in App.js.
So instead of:
const App = () => {
return (
<Fragment>
<Router>
<Switch>
<Route exact path='/' component={LandingPage} />
<Route exact path='/gitapp' component={GitApp} /> {/* Wrong! */}
<Route component={PageNotFound} />
</Switch>
</Router>
</Fragment>
);
};
It should be:
const App = () => {
return (
<Fragment>
<Router>
<Switch>
<Route exact path='/' component={LandingPage} />
<Route path='/gitapp' component={GitApp} /> {/* Correct! */}
<Route component={PageNotFound} />
</Switch>
</Router>
</Fragment>
);
};
Don't know exactly why but I can reload the second level components instead of receiving the NotFound Component. Would appreciate it if someone could explain why the word exact made a different here.
As for my second issue, I just used redirect with conditional rendering. So my context api will update my global 'logout' state and pass it down to the component which then would be waiting for it ('logout' state) to become true and will then redirect me to the landing page.

Categories

Resources