React does not render component to url's that uses dynamic routing - reactjs

I'm trying to match the url path to perform dynamic routing, but the component is not being Rendered at the path. What am i doing wrong here?
btw the route to the CollectionsOverview component is working.
Shop Component.js :
https://imgur.com/Z7P4jjH
onst ShopPage = ({ match }) => {
console.log(`Shop Component ${match.path}`);
return (
<div className='shop-page'>
<Switch>
<Route exact path={`/${match.path}`} component={CollectionsOverview} />
<Route
path={`/${match.path}/:collectionId`}
component={CollectionPage}
/>
</Switch>
</div>
);
};
export default ShopPage;
Collection Component.js:
https://imgur.com/Wu36EAV
const CollectionPage = () => {
console.log(`Collection Page`);
return (
<div className='collection-page'>
<h2>Hello</h2>
</div>
);
};
Result:
https://imgur.com/UccQgB8

Put /${match.path}/:collectionId path before /${match.path} and remove exact from route.
Here is working code: https://codesandbox.io/s/react-router-dynamic-routing-r714l
import React, { useEffect } from "react";
import ReactDOM from "react-dom";
import { BrowserRouter, Route, Switch, Link } from "react-router-dom";
const CollectionOverview = () => {
return (
<div>
<div>CollectionOverview</div> <br />
<Link to="/collection/1">To Collection 1</Link> <br />
<Link to="/collection/2">To Collection 2</Link> <br />
<Link to="/collection/3">To Collection 3</Link> <br />
<Link to="/collection/4">To Collection 4</Link> <br />
</div>
);
};
const CollectionPage = props => {
return <div>CollectionPage for ID: {props.match.params.id}</div>;
};
const HomeComponent = () => {
return <div>Home Component</div>;
};
function App() {
return (
<BrowserRouter>
<div>
<Link to="/">To Home</Link>
<br />
<Link to="/collection">To Collection Overview</Link>
<br />
</div>
<Switch>
<Route path="/collection/:id" component={CollectionPage} />
<Route path="/collection" component={CollectionOverview} />
<Route path="/" component={HomeComponent} />
</Switch>
</BrowserRouter>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

Related

Redirections with React

I'm trying to have a Home Page and with differents links redirect to the differents pages of my app.
I used <Routes> and <Route> to redirect them but is not working. It stay in blank.
I want to Navebar be the layout here, so I read that it must contain the other Routes inside of it
import React from 'react';
import { Route, Routes } from 'react-router';
import './App.scss';
import Navbar from './components/Navbar/Navbar'
import Home from './components/Home/index'
import Contact from './components/Contact'
const App = () => {
return (
<>
<Routes>
<Route path='/' element={<Navbar/>}>
<Route exact={true} index element={<Home/>}></Route>
<Route exact={true} path='contact' element={<Contact/>}></Route>
</Route>
</Routes>
</>
);
}
export default App;
index.js
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>
);
This is the Navbar (which is the onlyone is showing)
class Navbar extends Component{
state = { clicked: false}
handleClick = () =>{
this.setState({clicked: !this.state.clicked})
}
render(){
return(
<>
<nav className='navbar-items'>
<img alt='mRadio' className='navbar-logo' href="../Home/index" src={require('../../assets/images/mRadio.png')}></img>
<div className='menu-icon' onClick={this.handleClick}>
<i className={this.state.clicked ? 'fas fa-times' : 'fas fa-bars'}></i>
</div>
<ul className={this.state.clicked ? 'nav-menu active' : 'nav-menu'}>
{MenuItems.map((item, index)=>{
return (
<li key={index}>
<a className={item.cName} href={item.url}>{item.title}</a>
</li>
)
})
}
</ul>
</nav>
</>
)
}
}
And this is the Home page:
const Index = () => {
return (
<div className='main'>
<video src={videomRadio} autoPlay loop muted/>
</div>
);
}
And this is a Third page:
const Index = () => {
return (
<div>
<p>CONTACT PAGE</p>
</div>
);
}
If you re using the latest version 6, don't use Switch, now is become Routes, try to change the path like this for example if is nested component:
import { Route, Routes } from 'react-router-dom'; //just in case
//...
const App = () => {
return (
<>
<Routes>
<Route path='/' element={<Navbar/>}>
<Route index element={<Home/>} />
<Route path='contact' element={<Contact/>}/>
</Route>
</Routes>
</>
);
}
export default App;
create a child in home and third page.that gives access to that page directly.

problem rendering pages using react-router-dom getting warning msg: router.ts:11 No routes matched location "/charterdetails"

I'm new to react and I'm trying to build application to make reservation for fishing charters for a school project I'm working on. I'm using react-router-dom which works for the most part, but when I try and use a button to navigate to page it does not render components on 2 of the pages. The page will refresh but it does not render the components "CharterDetails" or "BookCharter".
I get no errors but I do get a warning that says:
No routes matched location "/charterdetails/62fb097cb985e11cb3884f6e"
It does not seem to matter if I use the button handler or just a link both options give the same result for both CharterDetails and BookCharter, navigation for other pages render as expected.
Click here for my GitHub repository
select the work-in-progress branch
hope I’m explaining clear enough. Thank for your time
App.js:
import React, { useState, useEffect } from "react";
import Nav from "./Components/Nav";
import {
BrowserRouter as Router,
Route,
Routes,
useParams,
} from "react-router-dom";
import Login from "./Components/Users/LoginForm";
import "./App.css";
import Landings from "./Pages/Landings.js";
import Boats from "./Pages/Boats";
import Charters from "./Pages/Charters";
import CharterDetails from "./Pages/CharterDetails";
import BookCharter from "./Pages/BookCharter";
import PageNotFound from "./Pages/404";
import Home from "./Pages/Home";
function App() {
const { id } = useParams();
console.log("useParams", id);
return (
<>
<header>
<img
src="../assets/Images/scsfcBadge.png"
alt="SoCal Sportfishing Club"
/>
SoCal Sportfishing Club
</header>
<div className="main">
<Router>
<aside className="left">
<Nav />
</aside>
<main>
<Routes>
<Route index element={<Home />} />
<Route path="/charters" element={<Charters />} />
<Route path="/landings" element={<Landings />} />
<Route path="/boats" element={<Boats />} />
{/* need to add parameter :id to link */}
<Route page="/bookcharter/" element={<BookCharter />} />
{/* need to add parameter :id to link */}
<Route page="/charterdetails/:id" element={<CharterDetails />} />
<Route page="*" element={<PageNotFound />} />
</Routes>
</main>
<aside className="right">
<Login />
</aside>
</Router>
</div>
<footer>Copyright © 2022 SoCal SportFishing Club </footer>
</>
);
}
export default App;
Home.js:
import React,{useState , useEffect} from 'react';
import { Link, useNavigate } from "react-router-dom";
import { BrowserRouter as Router, Route, Routes, useParams } from "react-router-dom";
function Home(){
const navigate = useNavigate();
const [charterData, setCharterData] = useState([]);
const [charterid, setCharterid] = useState('');
useEffect(() => {
// declare the async data fetching function
const fetchData = async () => {
fetch('http://localhost:5000/charter/featured/')
.then((response) => response.json())
.then((data) => setCharterData(data));
console.log('Charter ', charterData)
}
// call the function
fetchData()
// make sure to catch any error
.catch(console.error);
}, [])
function handleClick(charter) {
let id = charter.id;
let path = `/charterdetails//${id}`
navigate(path);
}
function BookClick(e) {
// e.preventDefault();
let path = `/bookcharter/${e.target.id}`
navigate(path);
}
return(
<div className="container">
{
charterData.map((charter, index) => {
return(<div key={index} className="card">
<div className="card-header">
</div>
<img src={'../assets/Images/charters/' + charter.Img} alt={charter.CharterName} />
<div className="tag tag-teal">{charter.BoatName} - {charter.Duration}</div>
<div className="card-body">
<div style={{fontSize:'28px', fontWeight: 'Bold'}}>
{charter.CharterName}
</div>
<p style={{fontSize:'16px'}}>Departure date: {new Date(charter.Departure).toDateString()}<br />
Return date: {new Date(charter.Return).toDateString()}<br />
Trip Duration: {charter.Duration}<br />
Price: ${charter.Cost}<br />
Max Load:{charter.MaxLoad}<br />
Target: {charter.Target}<br /></p>
<div style={{textAlign:'center', width: '100%'}}>
<Link
to= {{
pathname:`/charterdetails/${charter.id}`
}}
>
<button>Details</button>
</Link>
<button onClick={BookClick}>Book</button>
</div>
</div>
</div>)
})
}
</div>
)
}
export default Home;
Nav.js:
import React from 'react';
import { Link } from "react-router-dom";
export default function Nav() {
return (
<>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/landings">Landings</Link>
</li>
<li>
<Link to="/boats">Boats</Link>
</li>
<li>
<Link to="/charters">Club Charters</Link>
</li>
<li>
<Link to="/charterdetails">Charter Details</Link>
</li>
<li>
<Link to="/bookcharter">Book Charter</Link>
</li>
</ul>
</>
);
}
CharterDetails.js:
import React from 'react';
function CharterDetails(){
return(
<div>
Charter Details
</div>
)
}
export default CharterDetails;
BookCharter.js:
import React from "react";
function BookCharter(){
return(
<>
Book Charter
</>
)
}
export default BookCharter;
In the app.js I had page instead of path on the route.
Changed from
<Route page="/bookcharter" element={<BookCharter />} />
<Route page="/charterdetails/:id" element={<CharterDetails />} />
to
<Route exact path="/bookcharter" element={<BookCharter />} />
<Route exact path="/charterdetails/:id" element={<CharterDetails />} />

`No routes matched location "/" ` warning shown on the console

I am trying to implement a small project and got an error/warning like above title.
Here is my Index.jsx:
import React, { Suspense } from "react";
import ReactDOM from "react-dom";
import { Provider } from "react-redux";
import { BrowserRouter} from "react-router-dom";
import { App } from "./components/app";
ReactDOM.render(
<React.StrictMode>
<Provider store={store}>
<Suspense fallback={<div>Loading...</div>}>
<BrowserRouter>
<App />
</BrowserRouter>
</Suspense>
</Provider>
</React.StrictMode>,
document.getElementById("root")
);
App.jsx:
import React, { useEffect } from "react";
import { makeStyles } from "#material-ui/core/styles";
import { Container } from "#material-ui/core";
import { ToastContainer } from "react-toastify";
import { Route, Routes } from "react-router-dom";
import { useSelector, useDispatch } from "react-redux";
import Sidebar from "../sidebar/Sidebar";
import TopNav from "../topnav/TopNav";
import { AppRoutes } from "../AppRoutes";
import ThemeAction from "../../store/actions/ThemeAction";
import "./App.scss";
const useStyles = makeStyles({
contentStyle: {
margin: "30px auto",
},
});
export const App = () => {
const themeReducer = useSelector((state) => state.ThemeReducer);
const classes = useStyles();
const dispatch = useDispatch();
useEffect(() => {
const themeClass = localStorage.getItem("themeMode", "theme-mode-light");
const colorClass = localStorage.getItem("colorMode", "theme-mode-light");
dispatch(ThemeAction.setMode(themeClass));
dispatch(ThemeAction.setColor(colorClass));
}, [dispatch]);
return (
<Routes>
<Route
render={(routeProps) => (
<div className={`app ${themeReducer.mode} ${themeReducer.color}`}>
<Sidebar routeProps={routeProps} />
<div className="app__content">
<TopNav />
<div className="app__content-main">
<ToastContainer />
<Container className={classes.contentStyle} maxWidth="sm">
<AppRoutes />
</Container>
</div>
</div>
</div>
)}
/>
</Routes>
);
};
And AppRoutes.jsx:
import React from "react";
import { Route, Routes } from "react-router-dom";
import Customers from "../pages/Customers";
import { Dashboard } from "../pages/Dashboard";
import { UserLogin } from "./User/Login";
import { UserSignup } from "./User/Signup/UserSignup";
export const AppRoutes = () => {
return (
<Routes>
<Route index path="/" element={<Dashboard />} />
<Route path="customers" component={<Customers />} />
<Route path="userLogin" element={<UserLogin />} />
<Route path="userSignup" element={<UserSignup />} />
</Routes>
);
};
And the project is not running) I mean white blank on browser window while there is no error except index.tsx:25 No routes matched location "/" .
In react-router-dom#6 there are no longer any render (or component or children function props). Remove the Routes and Route component in App. You will also update Sidebar to access the location object via hook.
App
return (
<div className={`app ${themeReducer.mode} ${themeReducer.color}`}>
<Sidebar routeProps={routeProps} />
<div className="app__content">
<TopNav />
<div className="app__content-main">
<ToastContainer />
<Container className={classes.contentStyle} maxWidth="sm">
<AppRoutes />
</Container>
</div>
</div>
</div>
);
Sidebar
const Sidebar = () => {
const location = useLocation();
const activeItem = sidebar_items.findIndex(
(item) => item.route === location.pathname
);
return (
<div className="sidebar">
<div className="sidebar__logo">
<img src={logo} alt="company logo" />
</div>
{sidebar_items.map((item, index) => (
<Link to={item.route} key={index}>
<SidebarItem
title={item.display_name}
icon={item.icon}
active={index === activeItem}
/>
</Link>
))}
</div>
);
};
AppRoutes
Remove the index prop from the "/" route. When you specify an index route the path prop is ignored. Also, make sure all the routes are correctly using the element prop.
<Routes>
<Route path="/" element={<Dashboard />} />
<Route path="customers" element={<Customers />} />
<Route path="userLogin" element={<UserLogin />} />
<Route path="userSignup" element={<UserSignup />} />
</Routes>

Infinite Loop in Reach Router

I'm a bit new to React and it is my first time using reach-router (or any kind of router really). What I'm trying to do is have a nested component inside one of my router links. Basically, within my ItemShop component, I want to have two more links to components (both of which are defined within my ItemShop component), and I want to display whichever component is selected under the navbar. It seems similar to something they do in the tutorial, but for some reason I seem to get an infinite loop when I click on a link.
Here is my top-level router, in App.js:
function App() {
return (
<div>
<Router>
<HomePage path="/" />
<ItemShop path="ItemShop" />
<Item path="ItemShop/:id" />
<Challenge path="Challenge" />
<Achievements path="Achievements" />
<BattlePass path="BattlePass" />
<Miscellaneous path="Miscellaneous" />
</Router>
</div>
);
}
And this is my ItemShop component where I'm trying to render the links, ItemShop.js:
render() {
// ... assigning arrays here
let Current = () => ( //...);
let Upcoming = () => ( //...);
return(
<>
<div className="nav-container">
<Navbar />
</div>
//...
<div>
<nav className="side-nav">
<Link to="/current">Current</Link>{" "}
<Link to="/upcoming">Upcoming</Link>
</nav>
<Router>
<Current path="current" />
<Upcoming path="upcoming" />
</Router>
</div>
//...
{this.props.children}
)
}
}
Again I am very new to Javascript/React as a whole, so it could just be a fundamental flaw. I have already sunk quite a few hours into this so I would really appreciate some guidance. Thank you for your time!
I tried using React-Router-Dom instead of reach-router. I made it so it renders both <Upcoming /> and <Current /> components inside of the <ItemShop /> component. You can check it out how I have done it below. I hope this helps.
// import React from "react";
// import { BrowserRouter as Router, Route, Switch, Link } from "react-router-dom";
export default function App() {
return (
<div className="App">
<Router>
<Switch>
<Route exact path="/" component={HomePage} />
<Route path="/itemShop" component={ItemShop} />
<Route path="/itemShop/:id" component={Item} />
<Route path="/challenge" component={Challenge} />
<Route path="/achievements" component={Achievements} />
<Route path="/battlePass" component={BattlePass} />
<Route path="/miscellaneous" component={Miscellaneous} />
</Switch>
</Router>
</div>
);
}
const HomePage = () => {
return <div>Home Page</div>;
};
const ItemShop = () => {
const Current = () => {
return <div>Current</div>;
};
const Upcoming = () => {
return <div>Upcoming</div>;
};
return (
<div>
<div>Item Shop</div>
<Link to="/itemShop/current">Current</Link>{" "}
<Link to="/itemShop/upcoming">Upcoming</Link>
<br />
<br />
<Route
render={() =>
window.location.pathname === `/itemShop/current` ? (
<Current />
) : (
<Upcoming />
)
}
/>
</div>
);
};
const Item = () => {
return <div>Item</div>;
};
const Challenge = () => {
return <div>Challenge</div>;
};
const Achievements = () => {
return <div>Achievements</div>;
};
const BattlePass = () => {
return <div>BattlePass</div>;
};
const Miscellaneous = () => {
return <div>Miscellaneous</div>;
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-router-dom/6.0.0-beta.0/react-router-dom.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

React Router Inserting Content into the BaseLayout

I have a single page React app. I have a BaseLayout component which serves as the container for the app. BaseLayout displays the header and footer and also the content as shown below:
class App extends Component {
render() {
return (
<div>
<BaseLayout>
</BaseLayout>
</div>
);
}
}
BaseLayout
export default class BaseLayout extends Component {
render() {
return (
<div>
<NavBar />
{this.props.children}
<Footer />
</div>
)
}
}
index.js
ReactDOM.render(
<BrowserRouter>
<Switch>
<Route path="/page_one" component={PageOne} />
<Route path="/page_two" component={PageTwo} />
<Route path="/" component={App} />
</Switch>
</BrowserRouter>,
document.getElementById('root')
)
All the navigation is inside the navBar.js component.
navBar.js
export default class NavBar extends Component {
render() {
return (
<div className="nav-bar">
<button><Link to="/">Home</Link></button>
<button><Link to="/page_one">Page One</Link></button>
<button><Link to="/page_two">Page Two</Link></button>
</div>
)
}
}
pageOne.js and pageTwo.js
export default class PageOne extends Component {
constructor(props) {
super(props)
}
render() {
return (
<div>
<h1>Page One </h1>
</div>
);
}
}
The problem is that when I go to page_one or page_two URL it only shows the content of the component and not the navigation bar.
How can I make the navigation bar and footer visible on all the pages using react router and react framework?
UPDATE:
App.js
class App extends Component {
render() {
return (
<div>
<BaseLayout>
</BaseLayout>
</div>
);
}
}
export default App;
I changed my index.js to the following:
ReactDOM.render(
<BrowserRouter>
<Route path="/" component={App}>
<Switch>
<Route path="/page_one" component={PageOne} />
<Route path="/page_two" component={PageTwo} />
</Switch>
</Route>
</BrowserRouter>,
document.getElementById('root')
)
Now, I get the following:
And the page does not go anywhere if I use the above code:
I think you should "lift" the App as the root Route.
By the way, Is App the same as BaseLayout? hard to tell from your example.
Example:
const Index = () => {
return (
<BrowserRouter>
<div>
<Route component={App} />
<Switch>
<Route path="/page_one" component={PageOne} />
<Route path="/page_two" component={PageTwo} />
</Switch>
</div>
</BrowserRouter>
);
};
A running code example, i'm not using a stack snippet as i can't use react-route with push state here.
I'm posting the entire code in case the url will be broken in the future:
import React from "react";
import { render } from "react-dom";
import { BrowserRouter, Route, Link, Switch } from "react-router-dom";
const Footer = () => <div>Footer...</div>;
class BaseLayout extends React.Component {
render() {
return (
<div>
<NavBar />
{this.props.children}
<hr/>
<Footer />
</div>
);
}
}
class NavBar extends React.Component {
render() {
return (
<div className="nav-bar">
<button>
<Link to="/">Home</Link>
</button>
<button>
<Link to="/page_one">Page One</Link>
</button>
<button>
<Link to="/page_two">Page Two</Link>
</button>
</div>
);
}
}
const PageOne = () => <h1>Page One</h1>;
const PageTwo = () => <h1>Page Two</h1>;
class App extends React.Component {
render() {
return (
<div>
<BaseLayout>{this.props.children}</BaseLayout>
</div>
);
}
}
const Index = () => {
return (
<BrowserRouter>
<div>
<Route component={App} />
<Switch>
<Route path="/page_one" component={PageOne} />
<Route path="/page_two" component={PageTwo} />
</Switch>
</div>
</BrowserRouter>
);
};
render(<Index />, document.getElementById("root"));

Resources