How to get parameters through component on react-router-dom-6 - reactjs

I am new to React JS. I am learning react router dom version 6. I am having an problem. I am not getting parameters through components.
Here is my codes:
App.js
import React, { Component } from 'react';
import './App.css';
import Movies from './components/movies';
import Customers from './components/customers';
import Rentals from './components/rentals';
import NotFound from './components/not-found';
import Navbar from './components/navbar';
import MovieForm from './components/movieform'
import { Route, Routes, Navigate } from 'react-router-dom';
class App extends Component {
render() {
return (
<main>
<Navbar />
<Routes>
<Route path='/movies/:id' element={<MovieForm />} />
<Route path="/" element={<Navigate replace to="/movies" />} />
<Route path="/movies" element={<Movies />} />
<Route path="/customers" element={<Customers />} />
<Route path="/Rentals" element={<Rentals />} />
<Route path="*" element={<NotFound />} />
</Routes>
</main>
);
}
}
export default App;
moviesform.jsx
import React from 'react';
const MovieForm = props => {
console.log(props);
return (
<div className="container">
<h1>Movie Form </h1>
</div>
)
}
export default MovieForm;
I get this through React Developer Tools extension:
{
"children": "<MovieForm />",
"value": {
"outlet": null,
"matches": [
{
"params": "{id: \"5b21ca3eeb7f6fbccd471816\"}",
"pathname": "/movies/5b21ca3eeb7f6fbccd471816",
"pathnameBase": "/movies/5b21ca3eeb7f6fbccd471816",
"route": "{caseSensitive: undefined, element: <MovieForm />, …}"
}
]
}
}
How can I access the parameters?

You can use useParams to access params in react-router-dom v6
import React from 'react';
import { useParams } from 'react-router-dom';
const MovieForm = () => {
const params = useParams();
console.log(params);
return (
<div className="container">
<h1>Movie Form </h1>
</div>
)
}
export default MovieForm;

You can use the hook that react-router-dom provides called useParams
So to access your id parameter you'll have to go into your MovieForm component and use it there
import { useParams } from 'react-router-dom';
const MovieForm = props => {
const { id } = useParams();
console.log(props);
return (
<div className="container">
<h1>Movie Form </h1>
</div>
)
}

Related

I am haveing problem when i am try to change my class component in functional component in react js

app.js file code i want to convert it
import Toolbar from "./components/Toolbar";
// import Iqac from "./components/Iqac/iqac";
import React from "react";
import "./styles.css";
import SideDrawer from "./components/sidemenu/SideDrawer";
import BackDrop from "./components/backdrop/BackDrop";
import { Route, Router, Routes } from "react-router-dom";
class App extends React.Component {
state = {
};
drawerToggleClickHandler = () => {
this.setState(prevState => {
return { sideDrawerOpen: !prevState.sideDrawerOpen };
});
};
backDropClickHandler = () => {
this.setState({ sideDrawerOpen: false });
};
render() {
// let sideDrawer;
let backdrop;
if (this.state.sideDrawerOpen) {
// sideDrawer = <SideDrawer />;
backdrop = <BackDrop click={this.backDropClickHandler} />;
}
return (<>
<div className="tool">
<Toolbar drawerToggleClickHandler={this.drawerToggleClickHandler} />
<SideDrawer show={this.state.sideDrawerOpen} />
{backdrop}
</div>
</>
);
}
}
export default App;
i have tried to change also i want to impliment react router dom v6 so that is why is need to do this and i don't know how to do in react-class based component
import Toolbar from './components/Toolbar'
import Footer from './components/Footer'
import Home from './Pages/Home'
import { useState } from "react";
import About from "./Pages/About"
import {
BrowserRouter as Router,
Route,
Routes
} from "react-router-dom";
const App = () => {
const [state, setstate] = useState({
sideDrawerOpen: false
});
return (
<>
<Router>
<Toolbar />
<Routes>
<Route path='/' element={<Home />}> </Route>
<Route path='/about/*' element={<About />}> </Route>
</Routes>
</Router>
<Footer />
</>
);
}
export default App;
i want to use react router dom and i thing v6 does't work with class
component
please help me resolve this issue i need to lot of your support thankyou so much in advance for the help
Try to change your code like this:
import Toolbar from './components/Toolbar';
import Footer from './components/Footer';
import Home from './Pages/Home';
import { useState } from 'react';
import About from './Pages/About';
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';
const App = () => {
const [sideDrawerOpen, setSideDrawerOpen] = useState(false);
const drawerToggleClickHandler = () => {
setSideDrawerOpen((prevState) => !prevState);
};
const backDropClickHandler = () => {
setSideDrawerOpen(false);
};
return (
<div className='tool'>
<Toolbar drawerToggleClickHandler={drawerToggleClickHandler} />
<SideDrawer show={sideDrawerOpen} />
{sideDrawerOpen && <BackDrop click={backDropClickHandler} />}
<Router>
<Toolbar />
<Routes>
<Route path='/' element={<Home />}>
{' '}
</Route>
<Route path='/about/*' element={<About />}>
{' '}
</Route>
</Routes>
</Router>
<Footer />
</div>
);
};
export default App;

Best practise: Where to put the Navbar component so that it -re-renders with every page?

This has been bugging me for a long time, and my head just can't seem to come up with a solution that works fluently. I will try to be short:
I have a React app where I update my Navbar based on an access token being stored as a cookie or not (user authenticated or not). But in order for my Navbar to update whether the user is authenticated, I have to refresh the page. I believe it is because my Navbar is being rendered way up (in?) the component tree, and does not get re-rendered whenever I visit a new page (only when I refresh).
What is the best way to render my Navbar component so that every page shares the same component, BUT the Navbar re-renders on every new page visited? Or is this even a wise thing to do?
Let me know if I am not explaining myself clearly.
index.jsx
import React from "react";
import ReactDOM from "react-dom";
import { App } from "./components/App";
import { BrowserRouter } from "react-router-dom";
import "./styles/styles.css";
import { PublicClientApplication } from "#azure/msal-browser";
import { MsalProvider } from "#azure/msal-react";
import { msalConfig } from "./lib/authConfig";
const msalInstance = new PublicClientApplication(msalConfig);
ReactDOM.render(
<MsalProvider instance={msalInstance}>
<BrowserRouter>
<App />
</BrowserRouter>
</MsalProvider>,
document.getElementById("root")
);
App.jsx
import React from "react";
import { Router } from "./Router";
import { Navbar } from "./Navbar";
export function App() {
return (
<div>
<Navbar />
<Router />
</div>
);
}
Router.jsx
import { Route } from "react-router-dom";
import React from "react";
import { MainPage } from "./MainPage";
import { LoginPage } from "./LoginPage";
import { GoogleLogin } from "./GoogleLogin";
import { GoogleLoginCallback } from "./GoogleLoginCallback";
import { GoogleLogout } from "./GoogleLogout";
import { NewArticle } from "./NewArticle";
export function Router() {
return (
<div>
<Route exact path="/" component={MainPage} />
<Route exact path="/login" component={LoginPage} />
<Route exact path="/login/google" component={GoogleLogin} />
<Route exact path="/logout/google" component={GoogleLogout} />
<Route exact path="/newArticle" component={NewArticle} />
<Route
exact
path="/login/google/callback"
component={GoogleLoginCallback}
/>
</div>
);
}
Navbar.jsx
import React, { useEffect, useState } from "react";
import { NavLink } from "react-router-dom";
import { useIsAuthenticated, useMsal } from "#azure/msal-react";
import { fetchJSON } from "../lib/fetchJSON";
export function Navbar() {
const activeStyle = {
borderBottom: "10px solid white",
};
const [username, setUsername] = useState();
const { accounts } = useMsal();
const name = accounts[0] && accounts[0].name;
const hasCookie = document.cookie.startsWith("access_token");
const isAuthenticated = useIsAuthenticated();
useEffect(async () => {
const res = await fetchJSON("/api/login/google");
if (hasCookie) {
setUsername(res.userinfo.given_name);
}
}, []);
return (
<>
<div className={"navbar-container"}>
<NavLink exact to="/" activeStyle={activeStyle}>
Home
</NavLink>
<NavLink exact to="/login" activeStyle={activeStyle}>
Login-portal
</NavLink>
{isAuthenticated ? (
<NavLink exact to="/newArticle" activeStyle={activeStyle}>
New Article
</NavLink>
) : (
<div />
)}
{isAuthenticated || hasCookie ? (
<p className="logged-in">
Logged in as {username} {name}
</p>
) : (
<p className="logged-in">Not logged in</p>
)}
</div>
</>
);
}

How to get id from json with axios get request

I'm trying to get idrestaurant for use as identifier from json document that has info like this on json objects on the database. Stuff is on PostgreSQL
This is a react website for a school project. I have tried printing response.data on a console log but nothing shows.
[{"idrestaurant":2,
"name":"Pizzeria Amigo",
"address":"Uusikatu 16",
"opening":"08:00",
"closing":"12:00",
"img":"testi.com/kuva.jpg",
"type":"fastfood",
"pricelvl":"3",
"owneruserid":1},
{"idrestaurant":3,
"name":"Burgers",
"address":"Katu 10",
"opening":"08:00",
"closing":"18:00",
"img":"testi.com/kuva.png",
"type":"fastfood",
"pricelvl":"1",
"owneruserid":1}]
I want to use id as idrestaurant as unique key for printing list of restaurant elements at Restaurant.js. Here is what I have been trying to do.
App.js
import React, { useEffect, useState } from 'react'
import './App.css'
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'
import NavBar from './components/navBar'
import Restaurants from './components/Restaurants'
import searchRestaurant from './components/Search'
import Restaurant from './components/Restaurant'
import axios from 'axios'
const App = () => {
const [restaurants, setRestaurants] = useState([])
useEffect(() => {
axios.get('http://MadeUpURL-app.herokuapp.com/restaurants')
.then((response) => {
setRestaurants(response.data)
});
}, []);
return (
<Router>
<div>
<NavBar />
<Routes>
<Route path='/restaurants' element={<Restaurants restaurants={restaurants} />} >
<Route path="/restaurants/idrestaurant" element={<Restaurant restaurants={restaurants} />} />
</Route>
{/* <Route path='/Search' element={<Search />} /> */}
</Routes>
</div>
</Router>
);
}
export default App
Restaurants.js
import React from 'react'
import styles from './restaurants.module.css'
import Restaurant from './Restaurant'
import { Link } from 'react-router-dom'
const Restaurants = (props) => {
return (
<div className={styles.container}>
<div className={styles.restaurantList}>
{props.restaurants.map(restaurant => <Link to={restaurant.idrestaurant}>
<Restaurant key={restaurant.idrestaurant} />
</Link>
)}
</div>
</div>
)
}
export default Restaurants
Restaurant.js
import React from 'react'
import styles from './restaurant.module.css'
export default function Restaurant(props) {
return (
<div className={styles.shop}>
<div>
<div><img src={props.img} className={styles.imageSize} /></div>
<div>
<div className={styles.title}>{props.name}</div>
<div className={styles.type}>{props.type}</div>
<div className={styles.prange}>{props.pricelvl}</div>
</div>
</div>
</div>
)
}
it is preferable to call api inside the Restaurants Component. Because setRestaurants will take time to update the state and in the mean time Restaurants Component will be render already so restaurants will be null in <Restaurants restaurants={restaurants} />
WORKING DEMO
Here is the code for App.js
import React, { useEffect, useState } from "react";
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
import Restaurants from "./components/Restaurants";
import Restaurant from "./components/Restaurant";
const App = () => {
return (
<Router>
<div>
<Routes>
<Route path="/" element={<Restaurants />} />
<Route path="/restaurants" element={<Restaurants />}>
<Route path="/restaurants/idrestaurant" element={<Restaurant />} />
</Route>
{/* <Route path='/Search' element={<Search />} /> */}
</Routes>
</div>
</Router>
);
};
export default App;
Here is the code for Restaurants.js
import React, { useEffect, useState } from "react";
import Restaurant from "./Restaurant";
import { Link } from "react-router-dom";
import axios from "axios";
const Restaurants = (props) => {
const [restaurants, setRestaurants] = useState([]);
const jsonFakeData = [
{
idrestaurant: 2,
name: "Pizzeria Amigo",
address: "Uusikatu 16",
opening: "08:00",
closing: "12:00",
img: "testi.com/kuva.jpg",
type: "fastfood",
pricelvl: "3",
owneruserid: 1
},
{
idrestaurant: 3,
name: "Burgers",
address: "Katu 10",
opening: "08:00",
closing: "18:00",
img: "testi.com/kuva.png",
type: "fastfood",
pricelvl: "1",
owneruserid: 1
}
];
useEffect(() => {
axios.get("https://jsonplaceholder.typicode.com/users").then((response) => {
console.log(response.data);
//setRestaurants(response.data);
setRestaurants(jsonFakeData);
});
}, []);
return (
<div>
<div>
{restaurants && restaurants.length > 0
? restaurants.map((restaurant) => (
<Link key={restaurant.idrestaurant} to={restaurant.idrestaurant}>
<Restaurant
restaurant={restaurant}
key={restaurant.idrestaurant}
/>
</Link>
))
: ""}
</div>
</div>
);
};
export default Restaurants;
Here is the code for Restaurant.js
import React from "react";
export default function Restaurant(props) {
console.log(props, "prps");
return (
<div>
<div>
<div>
<img src={props.restaurant.img} alt="img" />
</div>
<div>
<div>{props.restaurant.name}</div>
<div>{props.restaurant.type}</div>
<div>{props.restaurant.pricelvl}</div>
</div>
</div>
</div>
);
}

How to redirect to completely new page after user click in react?

I have a parent component which is rendering some stuff and a child component which is getting some props from parent component. And when user click button in Parent then it should redirect to completely new Page of child componen.
Parent Component
import React from "react";`enter code here`
import "./styles.css";
import { BrowserRouter as Router, Link, Route, Switch } from 'react-router-dom'
import ChildComponent from './ChildComponent'
export default function App() {
const someData = {
name : "Joh Doe"
}
return (
<div className="App">
<h1>This is parent Component</h1>
<Router>
<Link to='/secondpage'>Click me for Second Page</Link>
<Route
path='/secondpage'
render={(props) => (
<ChildComponent {...someData} isAuthed={true} />
)}
/>
</Router>
</div>
);
}
ChildComponent.js
import React from "react";
export default function ChildComponent(props) {
console.log("Data", props);
return <div>This is Second Page. It should open in new page. Also it should render incoming props</div>;
}
Work Demo
try doing this:
import React from 'react';
import {BrowserRouter as Router,Route, Redirect,Switch} from 'react-router-dom';
import Home from './App.js';
import Tutorials from './tutorials.js';
function Routes() {
return (
<Router>
<div>
<Switch>
<Route path="/" component = {Home}>
<Redirect from = "/blog/" to="/tutorials/" />
<Route path = "/tutorials/" component = {About} />
</Switch>
</div>
</Router>
)
}
i am change code .
parent component
import React from "react";
import { Link } from "react-router-dom";
export default function ParentComponent(props) {
console.log("Data", props);
return (
<div className="App">
<h1>This is parent Component</h1>
<Link to="/secondpage">Click me for Second Page</Link>
</div>
);
}
child component
import React from "react";
export default function ChildComponent(props) {
console.log("Data", props);
return (
<div>
This is Second Page. It should open in new page. Also it should render
incoming props
</div>
);
}
app component
import React from "react";
import "./styles.css";
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
import ChildComponent from "./ChildComponent";
import ParentComponent from "./parentComponent";
export default function App() {
const someData = {
name: "Joh Doe"
};
return (
<div className="App">
<Router>
<Switch>
<Route exact path="/secondpage">
<ChildComponent {...someData} isAuthed={true} />
</Route>
<Route exact path="/" component={ParentComponent} />
</Switch>
</Router>
</div>
);
}
Work Demo

Should not use <Link> outside a <Router> Error

I am trying to navigate through different screens with BottomNavigationAction from material ui and i get this error You should not use <Link> outside a <Router>
Tab.js:
import React from 'react';
import { Link } from 'react-router-dom';
import { withStyles } from '#material-ui/core/styles';
import BottomNavigation from '#material-ui/core/BottomNavigation';
import BottomNavigationAction from '#material-ui/core/BottomNavigationAction';
// icons
import HomeIcon from '#material-ui/icons/Home';
import DashboardIcon from '#material-ui/icons/Dashboard';
import PaymentIcon from '#material-ui/icons/Payment';
import FaceIcon from '#material-ui/icons/Face';
import AtmIcon from '#material-ui/icons/Atm';
const styles = {
root: {
position: 'absolute',
bottom: 0,
width: '100%',
cursor: 'pointer'
},
wrapper: {
minWidth: '0px'
}
};
class Tab extends React.Component {
state = { value: 0 };
handleChange = (event, value) => {
this.setState({ value });
};
render() {
const { classes } = this.props;
const { value } = this.state;
return (
<div>
<BottomNavigation value={value} onChange={this.handleChange} className={classes.root}>
<Link to="/">
<BottomNavigationAction label="Home" value="home" icon={<HomeIcon />} className={classes.wrapper}/>
</Link>
</BottomNavigation>
</div>
);
}
}
export default withStyles(styles)(Tab);
app.js is where i am trying to render the Tab.js so it stays on all the pages! and my routes are also rendered there
App.js
import React, { Component } from 'react';
import {BrowserRouter} from 'react-router-dom';
import Routers from './Routers';
import Tab from './components/Tab';
class App extends Component {
render() {
return (
<div>
<Tab />
<Routers />
</div>
);
}
}
export default App;
routes.js is where i identify routes:
Routes.js
import React from 'react';
import { BrowserRouter, Route, Switch, Redirect } from 'react-router-dom';
import { createStore, applyMiddleware } from 'redux';
import promise from 'redux-promise';
import { Provider } from 'react-redux';
import Home from './components/Home';
import Profile from './components/Profile';
import Login from './components/auth/Login';
import reducers from './reducers';
import configureStore from './store/configueStore';
import {getAuthToken} from './actions/auth';
const store = configureStore();
const Routers = () => (
<Provider store={store}>
<BrowserRouter>
<div>
<Switch>
<Route path='/' component={Home} exact={true}/>
<Route path='/login' component={Login} exact={true}/>
<Route path='/register' component={Login} exact={true}/>
<Route path='/profile' component={Profile} exact={true}/>
</Switch>
</div>
</BrowserRouter>
</Provider>
);
export default Routers;
how to i use link in my Tab.js file and make the redirection happen
and i will love an explanation on why this problem is accruing and how will i be able to fix it with my current file structure.
And is my file structure good? as i am having a different file for my routes and rendering it inside my app.js
Your Link and Routes must all have a Router provider higher up in the tree. Also you must use a single BrowserRouter. You can change your configuration to the following
const Routers = () => (
<div>
<Switch>
<Route path='/' component={Home} exact={true}/>
<Route path='/login' component={Login} exact={true}/>
<Route path='/register' component={Login} exact={true}/>
<Route path='/profile' component={Profile} exact={true}/>
</Switch>
</div>
);
class App extends Component {
render() {
return (
<div>
<Provider store={store}>
<BrowserRouter>
<div>
<Tab />
<Routers />
</div>
</BrowserRouter>
</Provider>
</div>
);
}
}
You don't have <BrowserRouter> parent for the link used in your tab.js file. Make following changes to your App.js file to make your code work:
import React, { Component } from 'react';
import { BrowserRouter } from 'react-router-dom';
import Routers from './Routers';
import Tab from './components/Tab';
class App extends Component {
render() {
return (
<BrowserRouter>
<div>
<Tab />
<Routers />
</div>
</BrowserRouter />
);
}
}
export default App;
I think you should wrap in .
For details you can also refer to Key Concepts For React-Router and React-Router With Material-UI

Resources