Why is my route not loading my React component? - javascript

I'm using react-router in my app for routing, where all of my routes work apart from the last one which is being used for modal purposes, however it's not loading the component.
function App() {
return (
<BrowserRouter basename="/veochorusapp">
<ModalSwitch />
</BrowserRouter>
);
}
export default App;
function ModalSwitch() {
let location = useLocation();
let background = location.state && location.state.background;
return (
<div className="App">
<Switch location={background || location}>
<Route exact path="/" component={Home} />
<Route path="/applications" component={Applications} />
<Route path="/waterType" component={WaterType} />
<Route path="/feedType" component={FeedType} />
<Route path="/products/:productName" component={Product} />
<Route path="/products" component={Products} />
<Route path="/interactive" component={ProductView} />
</Switch>
{background && <Route path="/feature/:id" children={<Modal />} />}
{background && <Route path="/accessory/:id" children={<AccessoryModal />} />}
</div>
);
}
The route that is not loading the component is the following:
{background && <Route path="/accessory/:id" children={<AccessoryModal />} />}
The code that links to this route is as below. I have used the same process on a previous component which works perfectly.
function AccessoryBtns() {
let location = useLocation();
return (
<ul className="accessoryBtns">
{AccessoriesData.map((i, index) => (
<li key={index}>
<Link
key={i.id}
className="btn"
to={{
pathname: `/accessory/${i.id}`,
state: { background: location }
}}
>
{i.name}
</Link>
</li>
))}
</ul>
)
}
export function AccessoryModal() {
let history = useHistory();
let { id } = useParams();
let accessory = AccessoriesData[parseInt(id, 10)];
if (!accessory) return null;
let back = e => {
e.stopPropagation();
history.goBack();
};
return (
<div className="modal">
<div className="row">
<div className="col-md-6 text-right">
Image
</div>
<div className="col-md-6">
<h2>{accessory.name}</h2>
<p>{accessory.description}</p>
</div>
</div>
<div className="backBtn" onClick={back}><FontAwesomeIcon icon={faArrowLeft} /></div>
</div>
);
}

First, it looks they are not inside <Switch>. Second, according to router docs, children must be a function
{background && <Route path="/feature/:id" children={() => <Modal />} />}
But since you pass no props to Modal you can simply use
{background && <Route path="/feature/:id">
<Modal />
</Route>}
or
{background && <Route path="/feature/:id" component={Modal} />}

Related

React-router outlet confusion

Why my outlet is not working in react-router-dom. All my components worked fine until I use Outlet and after using outlet my navigation component is not showing while other component seems to render.
import Home from "./Routes/Home/Home.component";
import { Routes, Route, Outlet } from "react-router-dom";
const Navigation = () => {
return (
<div>
<div>
<h1>Hello I am Navigation!!!</h1>
</div>
<Outlet />
</div>
);
};
const Shop = () => {
return <h2>I am shop component</h2>
}
const App = () => {
return (
<Routes>
<Route path='/' element={<Navigation />} />
<Route index element={<Home />} />
<Route path='shop' element={<Shop />} />
</Routes>
);
};
export default App;
I am receiving this:
enter image description here
and I want navigation component to render all above and persist every time I navigate to elsewhere.
for using of Outlet you need Add children to Route Component
const App = () => {
return (
<Routes>
<Route path='/' element={<Navigation/>}>
<Route path="url1" element{<ChildElemnt1 />} />
<Route path="url2" element{<ChildElemnt2 />} />
<Route path="url3" element{<ChildElemnt3 />} />
...
</Route>
<Route index element={<Home />} />
<Route path='shop' element={<Shop/>}/>
</Routes>
);
};
The Navigation component isn't rendered as a layout route with nested routes, so nothing is rendered into the Outlet it is rendering. Navigation will also only render on path "/".
If you want the Navigation component to render always then you can render it alone outside the routes.
const Navigation = () => {
return (
<div>
<div>
<h1>Hello I am Navigation!!!</h1>
</div>
</div>
);
};
const App = () => {
return (
<>
<Navigation />
<Routes>
<Route path='/'>
<Route index element={<Home />} />
<Route path='shop' element={<Shop />} />
</Route>
</Routes>
</>
);
};
Or you can utilize it as a layout route such that it wraps nested routes that render their element into the Outlet.
const Navigation = () => {
return (
<div>
<div>
<h1>Hello I am Navigation!!!</h1>
</div>
<Outlet />
</div>
);
};
const App = () => {
return (
<Routes>
<Route path='/' element={<Navigation />} />
<Route index element={<Home />} />
<Route path='shop' element={<Shop />} />
</Route>
</Routes>
);
};

navigation in react router dom version 6.3.0 doesn't work proplery

I'm working on react website and I have a problem while navigating to any page
that when I scroll to a certain point in a home page for example then I try to navigate to another page I find the other page is rendered from the the bottom of the page not the top
routes.tsx file
const App: React.FC = () => (
<BrowserRouter>
<Layout className="layout">
<div style={{ marginBottom: "64px" }}>
<Header>
<AppHeader />
</Header>
</div>
<Content>
<div className="site-layout-content">
<Routes>
<Route path="/" element={<Home />} />
<Route path="/offers" element={<Login />} />
<Route path="/aboutUs" element={<AboutUs />} />
<Route path="/contactUs" element={<ContactUs />} />
<Route path="/placeDetails/:id" element={<PlaceDetails />} />
<Route path="/advantages" element={<Advantages />} />
</Routes>
</div>
</Content>
<Footer style={{ textAlign: "center" }}>
<AppFooter />
</Footer>
</Layout>
</BrowserRouter>
);
export default App;
header.tsx
const Index = () => {
const navigate = useNavigate();
return (
<Row className="header">
<Col span={12} className="header__logo">
<div className="header__logo--imgContainer" onClick={() => navigate("/")}>
<img src={logoImg} alt="logo" />
</div>
</Col>
<Col span={12} className="header__menu">
<ul className="ant-menu-overflow ant-menu ant-menu-root ant-menu-horizontal ant-menu-light ant-menu-rtl">
<li className="ant-menu-item">
<span onClick={() => navigate("/offers")}>{strings.header.offers}</span>
</li>
<li className="ant-menu-item">
<span onClick={() => navigate("/advantages")}>{strings.header.services}</span>
</li>
</ul>
</Col>
</Row>
);
};
export default Index;
you can simply use this helper component for this use case:
import { useEffect } from "react";
import { useLocation } from "react-router-dom";
export default function ScrollToTop() {
const { pathname } = useLocation();
useEffect(() => {
// "document.documentElement.scrollTo" is the magic for React Router Dom v6
document.documentElement.scrollTo({
top: 0,
left: 0,
behavior: "instant", // Optional if you want to skip the scrolling animation
});
}, [pathname]);
return null;
}
and then you can change above code like this:
const App: React.FC = () => (
<BrowserRouter>
<ScrollToTop/> // this is new helper component
<Layout className="layout">
<div style={{ marginBottom: "64px" }}>
<Header>
<AppHeader />
</Header>
</div>
<Content>
<div className="site-layout-content">
<Routes>
<Route path="/" element={<Home />} />
<Route path="/offers" element={<Login />} />
<Route path="/aboutUs" element={<AboutUs />} />
<Route path="/contactUs" element={<ContactUs />} />
<Route path="/placeDetails/:id" element={<PlaceDetails />} />
<Route path="/advantages" element={<Advantages />} />
</Routes>
</div>
</Content>
<Footer style={{ textAlign: "center" }}>
<AppFooter />
</Footer>
</Layout>
</BrowserRouter>
);
export default App;
This will reset the scroll position on top whenever route changes.

React Router v6 render component on same page

I'm trying to change some "state varibale" managed component rendering into react-routing.I am using react-router 6.3.
This is the App.js
function App() {
return (
<Router>
<Header />
<Selections />
<Routes>
<Route path='/:type' element={<PostMain />}>
<Route path=':comments' index element={<Comments />} />
</Route>
</Routes>
</Router>
);
}
This is the Component
const handleLoadComments = () => {
if (!comments) {
dispatch(loadCommentsByPost(props.permalink));
} else {
navigate(-1);
//navigate(`/${type}`)
//console.log(type);
}
}
return (
<div className="Post">npm
<div className='Post-header' >
<p>Subbreddit: {props.subreddit_name_prefixed}</p>
<p>{created(props.created_utc)}</p>
</div>
<Media post={props} />
<div className='Post-footer-container' >
<div className='Post-footer' >
<div className='Post-footer-votes'>
<img src={upVote} alt="upvote" />
<p style={{color: "green"}} > {props.ups} -</p>
<img src={downVote} alt='downvote' />
<p style={{color: "red"}} > {props.downs}</p>
</div>
<Link to={`${props.id}`} >
<div className='Post-footer-comments' onClick={handleLoadComments} >
<input type="image" className='Comments-image' src={commentImg} alt='comment bubble' />
<p>{props.num_comments}</p>
</div>
</Link>
</div>
{/* { loading && <div className='Loading-container' ><img src={Loading} alt='loading' className='Comment-loading' /></div>} */}
</div>
<Outlet />
{/* {comments && <Comments comments={comments} />} */}
</div>
);
}
My goal would be to render the comments under the post, i did it with local state and setState before but is there a way to do it with routing?
I can see the change in the url when i click on a comment, i tried "navigate(/${type})" but not even the url changed so i used "navigate(-1)"
But the Comments component doesn't render!
Thanks in Advance!
Try to remove the path from the comments route since it's the index it sould be there by default
function App() {
return (
<Router>
<Header />
<Selections />
<Routes>
<Route path='/:type' element={<PostMain />}>
{/* <Route path=':comments' index element={<Comments />} /> */}
<Route index element={<Comments />} />
</Route>
</Routes>
</Router>
);
}
in your current approach you need to navigate to /type/comments, but it should be just /type

Render specific react component based on the URL

App.js
function App() {
<div className="App">
<Router>
<Switch>
<Route exact path="/home" component={Home} />
<Route exact path="/search" component={Home} />
</Switch>
</Router>
</div>;
}
Home.js
function Home() {
const location = useLocation();
return (
<div className="home">
<Component1 />
{location.pathname === "/home" && <Feed />}
{location.pathname === "/search" && <Search />}
<Component2 />
</div>
);
}
This works perfectly as I want to render the Feed or Search component depending on the URL.
But, I want to know is it okay to use location.pathname or is there any better alternative?
You could do something like:
App.js
function App() {
return <div className="App">
<Router>
<Switch>
<Route exact path="/home" component={() => <Home showFeed/>} />
<Route exact path="/search" component={() => <Home showSearch/>} />
</Switch>
</Router>
</div>;
}
Home.js
function Home(props) {
const location = useLocation();
return (
<div className="home">
<Component1 />
{props.showFeed && <Feed />}
{props.showSearch && <Search />}
<Component2 />
</div>
);
}
This allows you to abstract away the Home component's dependency on any routing mechanism, and simply allows you to control whether certain elements appear or not from outside this component.
use home component as layout. This can be highly recommended. You can rename your home component as Layout. This is more flexible way.
function Home() {
const location = useLocation();
return (
<div className="home">
<Component1 />
{ props.children }
<Component2 />
</div>
);
}
In your app.js modify like bellow
function App() {
<div className="App">
<Router>
<Switch>
<Route exact path="/home">
<Home>
<Feed />
</Home>
</Route>
<Route exact path="/search">
<Home>
<Search/>
</Home>
</Route>
</Route>
</Switch>
</Router>
</div>;
}

reactjs: how to use TransitionGroup&CSSTransition with a redirect on login

I'm using Laravel & Reactjs with the react-router-dom. I have made a Reactjs login page that redirects the user to the dashboard home page but it doesn't use the csstransition animation. In the dashboard I have an navbar that works with the csstransition. So how can I make the login also with an transition.
login page redirect is true when positive login (inside the render function):
const { redirect } = this.state;
if (redirect) {
return <Redirect to='/home'/>;
}
animated switch:
//router
const AnimatedSwitch = withRouter(({ location, ...props }) => {
return (
<TransitionGroup>
<CSSTransition key={location.key} classNames="slide" timeout={350}>
<Switch location={location}>
<Route exact path="/home" component={Dashboard} />
<Route exact path="/clients" render={() => <Clients />} />
<Route exact path="/login" component={() => <Login isAuth={props.isAuth} />} />
</Switch>
</CSSTransition>
</TransitionGroup>
)
});
app render:
render() {
if (this.state.auth) {
return (
<div className="wrapper">
<BrowserRouter>
<Sidebar />
<div className="main-panel">
<div className="content">
<AnimatedSwitch isAuth={this.isAuth}/>
</div>
</div>
</BrowserRouter>
</div>
);
} else {
return (
<div className="wrapper">
<BrowserRouter>
<div className="main-panel">
<AnimatedSwitch isAuth={this.isAuth}/>
</div>
</BrowserRouter>
</div>
);
}
}
}
Why does the Redirect not use the transition?

Categories