How to use :params in React router - javascript

Having issues with the react-router picking up on a nested route. A param is passed to accommodate for any subsequent links to be conditionally rendered later in the child component passed into Route
import React from "react";
import { Route } from "react-router-dom";
import CollectionsOverview from "../../components/collections-overview/collections-overview";
import CollectionPage from "../collection/collection";
const ShopPage = ({ match }) => {
return (
<div className="shop-page">
<Route exact path={`${match.path}`} component={CollectionsOverview} />
<Route path={`${match.path}/:collectionId`} component={CollectionPage} />
</div>
);
};
export default ShopPage;
import React from "react";
import "./collection.styles.scss";
const CollectionPage = ({ match }) => {
return (
<div className="collection-page">
<h2>COLLECTION PAGE: {match.params.collectionId}</h2>
</div>
);
};
export default CollectionPage;
Route 2 never renders its component on route manipulation

You can use useParams. Please check this example:
import React from "react";
import {BrowserRouter as Router,Switch,Route,Link,useParams} from "react-router-dom";
export default function ParamsExample() {
return (
<Router>
<div>
<h2>Accounts</h2>
<ul>
<li>
<Link to="/netflix">Netflix</Link>
</li>
<li>
<Link to="/zillow-group">Zillow Group</Link>
</li>
<li>
<Link to="/yahoo">Yahoo</Link>
</li>
<li>
<Link to="/modus-create">Modus Create</Link>
</li>
</ul>
<Switch>
<Route path="/:id" children={<Child />} />
</Switch>
</div>
</Router>
);
}
function Child() {
let { id } = useParams();
return (
<div>
<h3>ID: {id}</h3>
</div>
);
}
Source

Related

Why react is not rendering anything using router?

When I try to display the elements, I can't display anything, even with the <Link to=""> working fine.
I want a simple navbar using react-router-dom, to make a multiple pages web app.
I hope this error can be solved without any advanced code, cause I'm trying to learn the basics of React first.
App.js:
import './App.css';
import { useEffect, useState } from "react"
import axios from 'axios';
import React from "react"
import {
BrowserRouter as Router,
Routes,
Route,
Link
} from "react-router-dom"
import home from './home'
import userlist from './userlist'
function App() {
return (
<body>
<header>
<div className="divheadertitle">
<h1 className="headertitle">Tree.io</h1>
</div>
<Router>
<nav>
<ul>
<li><Link to="/">Home</Link></li>
<li><Link to="/userlist">User list</Link></li>
</ul>
</nav>
</Router>
<Router>
<Routes>
<Route path='/userlist' element={<userlist />} />
<Route path='/' element={<home />} />
</Routes>
</Router>
</header>
</body>
)
}
export default App;
userlist.js:
import React from "react"
import axios from 'axios'
import { useState, useEffect } from "react"
const userlist = () => {
const [listOfUsers, setListOfUsers] = useState([])
useEffect(() => {
axios.get('https://localhost:3001/userlist')
.then((response) => {
setListOfUsers(response.data)
})
})
return (
<div className="userlistdiv">
<h1>Lista de usuários:</h1>
{listOfUsers.map((user) => {
return(
<div className="userdiv">
<h1>Name: {user.name}</h1>
<h1>Age: {user.age}</h1>
<h1>E-mail: {user.email}</h1>
</div>
)
})}
</div>
)
}
export default userlist;
The links are rendered into a different router than the routes. React components are also Capitalized. Move all the links and routes into the same router.
import Home from './home'
import Userlist from './userlist'
function App() {
return (
<body>
<header>
<div className="divheadertitle">
<h1 className="headertitle">Tree.io</h1>
</div>
<Router>
<nav>
<ul>
<li><Link to="/">Home</Link></li>
<li><Link to="/userlist">User list</Link></li>
</ul>
</nav>
<Routes>
<Route path='/userlist' element={<Userlist />} />
<Route path='/' element={<Home />} />
</Routes>
</Router>
</header>
</body>
);
}
Additionally, the Userlist component is unconditionally fetching data and updating state, this is likely leading to some render looping. Add a dependency array.
useEffect(() => {
axios.get('https://localhost:3001/userlist')
.then((response) => {
setListOfUsers(response.data)
});
}, []); // <-- empty dependency array to run once on mount
Try this instead of function in your map method:
{
listOfUsers.map((user) =>(
<div className="userdiv">
<h1>Name: {user.name}</h1>
<h1>Age: {user.age}</h1>
<h1>E-mail: {user.email}</h1>
</div>
))
}
and make sure your api send your response truthly.
If you want to run an effect and clean it up only once, you can pass an empty array [ ] as dependency
I hope all of these be useful for you

React, how to pass product id to details page with React Router Dom?

I'm creating a page, like Amazon. In the index page, I have a list of products, and when the user clicks the link it goes to the product page that has all the details of the product, but for me to create this page I've to get the ID from the product but I can't get it.
App.js:
<main className="main">
<div className="content">
<Routes>
<Route path="/product/:id" element={<ProductScreen />} />
<Route path="/" exact element={<HomeScreen />} />
</Routes>
</div>
</main>
HomeScreen:
import React from 'react';
import data from "../data";
import { Link } from 'react-router-dom';
function HomeScreen(props) {
return (
<ul className="products">
{
data.products.map(product =>
<li>
<div className="product">
<Link to={'/product/' + product._id}>
<img
src={product.image}
alt="Product"
className="product-image"
/>
</Link>
<div className="product-name">
<Link to={'/product/' + product._id}>{product.name}</Link>
</div>
<div className="product-brand">{product.brand}</div>
<div className="product-price">{product.price}</div>
<div className="product-rating">{product.rating} Leafs ({product.numberReviews} Reviews)</div>
</div>
</li>
)
}
</ul>
);
}
export default HomeScreen;
ProductScreen:
import React from 'react';
import data from '../data';
function ProductScreen(props) {
console.log(props.match.params.id)
return <div>Product Screen</div>
}
export default ProductScreen;
I console.log it to see if everything was okay but the error shown is
TypeError: Cannot read properties of undefined (reading 'params')
What am I missing? I tried several kinds of stuff that I saw on the web.
You need to use useParams hook from React Router Dom. Like below:
import React from 'react';
import data from '../data';
import {useParams} from "react-router-dom"
function ProductScreen(props) {
const {id} = useParams();
console.log(id)
return <div>Product Screen</div>
}
export default ProductScreen;
After setting /product/:id router as you did:
<Route path="/product/:id" element={<ProductScreen />} />
For those who got no result, try this:
import React from 'react';
import data from '../data';
import {useParams} from "react-router-dom"
function ProductScreen(props) {
const params = useParams();
const id = params.id
console.log(id)
return <div>Product Screen</div>
}
export default ProductScreen;

How to setup Routes using React Router in my ReactJS app?

I have some problem with react-router. It doesn't go to Edit page when I click on id. The id is in URL, but it doesn't do anything.
const Main = (props) => {
const { pathname } = props.location;
return (
<Fragment>
<div>
<div className="container">
<Header />
{pathname === "/create" ? <Create /> : null}
{pathname === '/edit/:id' ? <Edit /> : null}
{pathname === "/" ? <Home /> : null}
</div>
</div>
</Fragment>
);
};
export default withRouter(Main);
app.js:
require('./components/Index');
import React from 'react'
import ReactDOM from "react-dom"
import Index from "./components/Index";
import { BrowserRouter as Router} from "react-router-dom";
import { ToastContainer } from 'react-toastify';
const App =() =>{
}
if (document.getElementById('app')) {
ReactDOM.render(<Router> <Index /> <ToastContainer /></Router>, document.getElementById('app'));
}
index.js:
import React from "react";
import { Route, Switch } from "react-router-dom";
import Main from "./CRUD/Main";
import Create from "./CRUD/Create";
import Edit from "./CRUD/Edit";
import Home from "./CRUD/Home";
const Index = (props) => {
return (
<Main>
<Switch>
<Route path="/Create" component={Create} />
<Route path='/edit/:id' component={Edit} />
<Route exact path="/" component={Home} />
</Switch>
</Main>
);
};
export default Index;
I think main.js have some problems with pathname.
You don't need to do conditional rendering like you are doing in Main when using react-router. Switch will automatically render the first child <Route> or <Redirect> that will match the location.
Hence, you need to remove Main from your router component i.e. Index so that it looks like as shown below:
const Index = (props) => {
return (
<>
<NavBar /> {/* NavBar is optional, I just added for example */}
<Switch>
<Route path="/create" component={Create} />
<Route path="/edit/:id" component={Edit} />
<Route exact path="/" component={Home} />
</Switch>
</>
);
}
NavBar: (Links; just for example)
function NavBar() {
return (
<ul>
<li>
<Link to="/create">Go to create</Link>
</li>
<li>
<Link to="/edit/123">Go to edit with id = 123</Link>
</li>
<li>
<Link to="/">Go to home</Link>
</li>
</ul>
);
}
Now, when you click on the above links, it will automatically take you to the related component (as declared in routes i.e. Index). (no manually condition checking)
And example, to retrieve the URL param i.e. id in Edit component using useParams hook:
function Edit() {
const { id } = useParams<{ id: string }>(); // Remove <{ id: string }> if not using TypeScript
return <h2>Edit, {id}</h2>;
}

React Router URL Change but Not Component

React Router change the URL but the component is not rendered
I have already looked for answer but none of those example is worked
Current React Router & React Router DOM version is 5.0.0
It's still plain create-react-app
I've tried to use Switch tag
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import { BrowserRouter as Router, Route, Link } from 'react-router-dom';
const Index = () => {
return <h2>Home</h2>;
};
const About = () => {
return <h2>About</h2>;
};
const Users = () => {
return <h2>Users</h2>;
};
class App extends Component {
render() {
return (
<Router>
<div className="App">
<header className="App-header">
<li>
<Link to="/">
<h1>Home</h1>
</Link>
</li>
<li>
<Link to="/about">
<h1>About</h1>
</Link>
</li>
<li>
<Link to="/users">
<h1>Users</h1>
</Link>
</li>
</header>
<hr />
<Route exact path="/" Component={Index} />
<Route path="/about" Component={About} />
<Route path="/users" Component={Users} />
</div>
</Router>
);
}
}
export default App;
It wont render the component
Try setting the 'component' attribute with lowercase c
I think it's a simple mistake. You capitalized the attribute word component in your Routes.

Why I can't import Constants from another file in Reactjs?

I was practicing React-Routing, I want to separate constants in another file away from my App.js. Basically, these constants are content for my pages that I want to be editable in a separate environment. But after importing them to App.js, it gives error "'React' must be in scope when using JSX react/react-in-jsx-".
Here is my App.js code:
import React from "react";
import "./App.css";
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
import {Home,About} from "./Constants.js";
class App extends React.Component {
render() {
return (
<Router>
<div>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
<Route exact path="/" component={Home} />
<Route exact path="/about" component={About} />
</div>
</Router>
);
}
}
export default App;
and Constants in Constants.js:
const Home = (
<div>
<h2>Home</h2>
</div>
);
const About = (
<div>
<h2>About</h2>
</div>
);
export { Home, About };
JSX gets compiled into React.createElement calls, so you need to import React if you are using JSX.
You should also write stateless functional components as functions, instead of as a React element directly.
import React from 'react';
const Home = () => (
<div>
<h2>Home</h2>
</div>
);
const About = () => (
<div>
<h2>About</h2>
</div>
);
export { Home, About };

Categories

Resources