react-router-dom v6: useNavigate() not working - reactjs

So I'm trying to redirect the Add to Cart button to Cart screen but it isn't working
ProductScreen.js
useNavigate() redirects to the link but doesn't display anything
import React, { useState, useEffect } from 'react'
import { Link, useParams, useNavigate } from 'react-router-dom'
import { useDispatch, useSelector } from 'react-redux'
const ProductScreen = () => {
const { id } = useParams()
const navigate = useNavigate()
const [ qty, setQty ] = useState(0)
const dispatch = useDispatch()
const productDetails = useSelector(state => state.productDetails)
const { loading, error, product } = productDetails
useEffect(() => {
dispatch(listProductDetails(id))
}, [dispatch])
return (
<>
<ListGroup.Item className='d-grid gap-2'>
<Button
onClick={() => navigate(`/cart/${id}?qty=${qty}`)}
className='btn-block'
type='button'
size='lg'
disabled={product.countInStock === 0}
> Add to Cart </Button>
</ListGroup.Item>
</>
)
}
CartScreen.js
const CartScreen = () => {
return (
<h1>Cart</h1>
)
}
export default CartScreen
App.js
import React from 'react'
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom'
import { Container } from 'react-bootstrap'
import Footer from './components/Footer'
import Header from './components/Header'
import HomeScreen from './screens/HomeScreen'
import ProductScreen from './screens/ProductScreen'
import CartScreen from './screens/CartScreen'
const App = () => {
return (
<Router>
<Header />
<main className='py-3'>
<Container>
<Routes>
<Route path='/' element={<HomeScreen />} exact />
<Route path='/product/:id' element={<ProductScreen />} />
<Route path='/cart' element={<CartScreen />}>
<Route path='/cart/:id?' element={<CartScreen />} />
</Route>
</Routes>
</Container>
</main>
<Footer />
</Router>
)
}
export default App
Now, this is where the problem lies. As far as I know, the cart screen should be displayed but all I get is a blank screen.
I get this one issue on console screen that I can't put my finger on
No routes matched location "/cart/6239f6707dfb138e900d42d7?qty=2"
I am very new to this coz everything has changed from the last version. I know this is very simple but I'm stuck here and can't go any further... Thanks for your help in advance

It seems like you maybe be using nested routes incorrectly in order to achieve what you are supposed to:
With this nesting:
<Route path='/cart' element={<CartScreen />}>
<Route path='/cart/:id?' element={<CartScreen />} />
</Route>
The above will match:
/cart/cart/6239f6707dfb138e900d42d7?qty=2
Shouldn't the nesting be?:
<Route path='/cart' element={<CartScreen />}>
<Route path='/:id?' element={<CartScreen />} />
</Route>
in order to to match:
/cart/6239f6707dfb138e900d42d7?qty=2

Perhaps you may have forgotten to use <Outlet /> to render content in <CartScreen />?

Related

Exit animation not working properly in react-transition-group with React router v6

I am working on a React website which is currently using react-transition-group#4.3.0 and react-router-dom#5.0.1. I am updating both the libraries to latest versions- react-transition-group#4.4.5 and react-router-dom#6.4.1.
Issue I am currently facing with the latest versions is that when I am going from routeA to routeB, routeB is rendering on top of routeA. Means, routeA is not unmounting from the UI. So, on the UI we have -
routeBComponent
routeAComponent
Here's the code of both files -
routes.js
import React, { lazy } from 'react';
import {
Route,
Navigate,
} from 'react-router-dom';
import AnimatedSwitch from './AnimatedSwitch';
const Home = lazy(() => import('views/Home'));
const Onboarding = lazy(() => import('views/Onboarding/Onboarding'));
const AppRoutes = () => (
<AnimatedSwitch>
<Route exact path="/" element={<Home />} />
<Route exact path="/onboarding" element={<Navigate to="/onboarding/1" />} />
<Route path="/onboarding/:step" element={<Onboarding />} />
</AnimatedSwitch>
);
export default AppRoutes;
AnimatedSwitch.js
import React from 'react';
import {
useLocation,
Routes,
} from 'react-router-dom';
import { TransitionGroup, CSSTransition } from 'react-transition-group';
import './AnimatedSwitch.scss';
const AnimatedSwitch = ({ children }) => {
const location = useLocation();
const timeout = { enter: 400, exit: 200 };
const direction = 'left';
return (
<TransitionGroup component="div" className="container">
<CSSTransition
key={location.key}
timeout={timeout}
classNames="pageSlider"
unmountOnExit
>
<div className={direction}>
<Routes location={location}>
{children}
</Routes>
</div>
</CSSTransition>
</TransitionGroup>
);
};
export default AnimatedSwitch;
Thanks for any help in Advance.

(react) only url change but page is not reloaded

import { useEffect, useState } from "react";
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
import Detail from "../components/Detail";
import Popular from "../components/Popular";
import Home from "../components/Home ";
import Trending from "../components/Trending";
import Upcoming from "../components/Upcoming";
import TopRated from "../components/TopRated";
import NowPlaying from "../components/NowPlaying";
function App() {
return (
<Router>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/popular-mv" element={<Popular type="movie" />} />
<Route path="/trending-mv" element={<Trending type="movie" />} />
<Route path="/topRated-mv" element={<TopRated type="movie" />} />
<Route path="/upcoming-mv" element={<Upcoming type="movie" />} />
<Route path="/nowPlaying-mv" element={<NowPlaying type="movie" />} />
<Route path="/popular-tv" element={<Popular type="tv" />} />
<Route path="/trending-tv" element={<Trending type="tv" />} />
<Route path="/topRated-tv" element={<TopRated type="tv" />} />
<Route path="/nowPlaying-tv" element={<NowPlaying type="tv" />} />
<Route path="/detail/:id/:type" element={<Detail />} />
</Routes>
</Router>
);
}
export default App;
import { useState, useEffect } from "react";
import { useParams, Link, useLocation } from "react-router-dom";
function Detail() {
const type =
useLocation().pathname.split("/")[
useLocation().pathname.split("/").length - 1
];
const URL = `https://api.themoviedb.org/3/${type}/`;
const { id } = useParams();
const [details, setDetails] = useState([]);
const [similars, setSimilars] = useState([]);
const [genres, setGenres] = useState([]);
function detailFetch() {
fetch(`${URL}${id}?api_key=${API_KEY}`)
.then((result) => result.json())
.then((json) => {
setDetails(json);
setGenres(json.genres);
});
}
function similarFetch() {
fetch(`${URL}${id}/similar?api_key=${API_KEY}`)
.then((result) => result.json())
.then((json) => {
setSimilars(json.results);
});
}
useEffect(() => {
detailFetch();
similarFetch();
}, []);
return (
<div>
<img src={`https://image.tmdb.org/t/p/w500/${details.poster_path}`} />
<div>{details.title}</div>
<div>{details.vote_average}</div>
<div>{details.release_date}</div>
<div>{details.runtime}</div>
<div>
{genres.map((g) => (
<li key={g.id}>{g.name}</li>
))}
</div>
<p>{details.overview}</p>
<div>
{similars.map((s) => (
<a href={`/detail/${s.id}/${type}`} key={s.id}>
<img src={`https://image.tmdb.org/t/p/w500/${s.poster_path}`} />
</a>
))}
</div>
</div>
);
}
export default Detail;
I'm making movieApp using react.
but i have some problems about routing.
As i said at title, in movie information(detail) page, i made this page load when clicking movie poster and its similar movies. and then i cliked similar movie poster, i expected to reload the page.
Actially i solve this problem using not using .
But i have question why this is not working when i using
(i have other pages like tv list,movie list. but it only occurs in detail page.)
Thank You!

Styles don't apply when using React.lazy

The problem is that when I start using React.lazy, input styles are not rendering correctly. With lazy I get default Antd input styles, not mine. What's the problem and how I can fix it? You can see my code and its results in the pictures below. Thanks!
This picture shows styles that this component should render
This picture shows what styles are applied when using lazy
Code with lazy
import { lazy, Suspense } from 'react';
import { Routes, Route, Navigate } from 'react-router-dom';
import { useAppSelector } from '../../../hooks/redux-hooks';
import { selectCurrentUser } from '../../../store/slices/user/userSelectors';
import { Spinner } from '../../common/Spinner/Spinner';
const HomePage = lazy(() => import('../../../pages/HomePage'));
const ShopPage = lazy(() => import('../../../pages/ShopPage'));
const CheckoutPage = lazy(() => import('../../../pages/CheckoutPage'));
const AuthPage = lazy(() => import('../../../pages/AuthPage'));
export const AppRoutes = () => {
const currentUser = useAppSelector(selectCurrentUser);
return (
<Suspense fallback={<Spinner />}>
<Routes>
<Route path="/" element={<HomePage />} />
<Route path="shop/*" element={<ShopPage />} />
<Route path="checkout" element={<CheckoutPage />} />
<Route
path="auth"
element={currentUser ? <Navigate to="/" /> : <AuthPage />}
/>
</Routes>
</Suspense>
);
};
Code without lazy
import { Routes, Route, Navigate } from 'react-router-dom';
import { useAppSelector } from '../../../hooks/redux-hooks';
import { selectCurrentUser } from '../../../store/slices/user/userSelectors';
import HomePage from '../../../pages/HomePage';
import ShopPage from '../../../pages/ShopPage';
import AuthPage from '../../../pages/AuthPage';
import CheckoutPage from '../../../pages/CheckoutPage';
export const AppRoutes = () => {
const currentUser = useAppSelector(selectCurrentUser);
return (
<Routes>
<Route path="/" element={<HomePage />} />
<Route path="shop/*" element={<ShopPage />} />
<Route path="checkout" element={<CheckoutPage />} />
<Route
path="auth"
element={currentUser ? <Navigate to="/" /> : <AuthPage />}
/>
</Routes>
);
};

My react onClick navigate shows URL, but does not render component

I am new to React router here and I am trying to make clicking on a recipe in my 'BrowseRecipes' page redirect to a page dedicated to that recipe. However, when I click on the recipe, the URL shows the correct URL /browse/${recipeID}, but the page I assign to this route does not render. Only the /browse page with a list of all the recipes renders. Does anyone know why?
Here is my APP.js
import AddNewRecipe from './components/AddNewRecipe'
import BrowseRecipes from './components/BrowseRecipes'
import { currentState } from './components/redux';
import ReactDOM from 'react-dom'
import { BrowserRouter as Router, Switch, Route, Routes, Link, useParams} from "react-router-dom";
import AuthReqPage from "./components/AuthReqPage"
import Navbar from "./components/Navbar"
import RecipePage from "./components/BrowseRecipes/RecipePage"
import PageNotFound from "./components/PageNotFound"
function App(props) {
return (
<Router>
<div className="App">
<Navbar />
<Routes>
<Route path='/add' element={<AddNewRecipe />} />
<Route path='/' element={<BrowseRecipes />} />
<Route path='/browse' element={<BrowseRecipes />}>
<Route path=':recipeID' element={<RecipePage />}/>
</Route>
<Route path='/authrequired' element={<AuthReqPage />} />
<Route path='/*' element={<PageNotFound />} />
</Routes>
</div>
</Router>
);
}
export default App;
Here is my BrowseRecipe component/page:
export function BrowseRecipes (props){
console.log('browseRecipe running')
let navigate = useNavigate()
let params=useParams()
console.log(params.recipeID)
if(props.recipeStore.length>0)
{
var displayRecipes = props.recipeStore.map(
elem=>
{
return (<li key={elem.recipeID} className='recipeDisplayBox' onClick={()=>navigate(`/browse/${elem.recipeID}`)}>
{elem.title},
Prep: {elem.prepTime.numeral} {elem.prepTime.unit}
</li>)
}
)
}
return(
<div>
<h1>Browse Recipes</h1>
<h2>Your recipes:</h2>
<ul>
{displayRecipes}
</ul>
</div>
)
}
const mapStateToProps=(state)=>{
return {recipeStore: state.recipe}}
export default connect(mapStateToProps)(RequireAuth(BrowseRecipes))
And here is the individual recipe page that failed to render:
export function RecipePage (props){
console.log('RecipePage running')
let params=useParams()
return(
<div>
<h1>{params.recipeID}</h1>
</div>
)
}
const mapStateToProps=(state)=>{
return {recipeStore: state.recipe}}
export default connect(mapStateToProps)(RequireAuth(RecipePage))
"RequireAuth" here is a higher-order component that redirects the page to 'Please Sign In' page if the user is not signed in.
Did I misunderstand something about the use of UseParams? Please help me shed some light! Thank you very much
You've rendered the RecipePage component on a nested route from the "/browse" route rendering the BrowseRecipes component.
<Route path='/browse' element={<BrowseRecipes />}>
<Route path=':recipeID' element={<RecipePage />}/>
</Route>
In this configuration the BrowseRecipes is required to render an Outlet component for the nested routes to be rendered into.
Example:
import { Outlet, useNavigate, useParams } from 'react-router-dom';
export function BrowseRecipes (props) {
const navigate = useNavigate();
const params = useParams();
let displayRecipes;
if (props.recipeStore.length) {
displayRecipes = props.recipeStore.map(elem => {
return (
<li
key={elem.recipeID}
className='recipeDisplayBox'
onClick={() => navigate(`/browse/${elem.recipeID}`)}
>
{elem.title},
Prep: {elem.prepTime.numeral} {elem.prepTime.unit}
</li>
);
});
}
return (
<div>
<h1>Browse Recipes</h1>
<h2>Your recipes:</h2>
<ul>
{displayRecipes}
</ul>
<Outlet /> // <-- nested routes render here
</div>
);
}
If you don't want to render both BrowseRecipes and RecipePage at the same time, then create a nested index route specifically for BrowseRecipes.
Example:
<Route path='/browse'>
<Route index element={<BrowseRecipes />} /> // <-- "/browse"
<Route path=':recipeID' element={<RecipePage />} /> // <-- "/browse/:recipeID"
</Route>
For more information, see:
Index Routes
Layout Routes

Seriously Stuck with React Router Issue URL change but not view or Render Components || React||Redux

When I click on My some Of Links That change Urls but not change view Or not render Components, I m Using React And Redux for developing App, That issue directly effecting app. My routeJs Or Application.js File is given Below.
import React, { useEffect } from 'react';
import './App.css';
import { Router, Route, Switch } from 'react-router-dom';
import history from './history';
import Navbar from './components/layouts/Navbar';
import Landing from './components/layouts/Landing';
import Register from './components/auth/Register';
import Login from './components/auth/Login';
import Alert from './components/layouts/Alert';
import { loadUser } from './actions/auth';
import { useDispatch } from 'react-redux';
import Dashboard from './components/dashboard/Dashboard';
import CreateProfile from './components/profile-form/CreateProfile';
import EditProfile from './components/profile-form/EditProfile';
import AddEducation from './components/profile-form/AddEducation';
import AddExperience from './components/profile-form/AddExperience';
import Profiles from './components/profiles/Profiles';
import Profile from './components/profile/Profile';
import Posts from './components/posts/Posts';
import PrivateRoute from './components/routing/PrivateRoute';
const App = () => {
const dispatch = useDispatch(() => loadUser());
useEffect(() => {
dispatch(loadUser());
}, [dispatch]);
return (
<Router history={history}>
<Navbar />
<Route exact path="/" component={Landing} />
<section className="container">
<Alert />
<Switch>
<Route exact path="/register" component={Register} />
<Route exact path="/login" component={Login} />
<Route exact path="/profiles" component={Profiles} />
<Route exact path="/profile/:id" component={Profile} />
<PrivateRoute exact path="/dashboard" component={Dashboard} />
<PrivateRoute exact path="/posts" component={Posts} />
<PrivateRoute
exact
path="/create-profile"
component={CreateProfile}
/>
<PrivateRoute exact path="/edit-profile" component={EditProfile} />
<PrivateRoute exact path="/add-education" component={AddEducation} />
<PrivateRoute
exact
path="/add-experience"
component={AddExperience}
/>
</Switch>
</section>
</Router>
);
};
export default App;
I asked this Question Several times on Different platforms got some valuable information but that still not works. here Is one Of my Component review it's code.
import React, { useEffect, Fragment } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { getCurrentUser } from '../../actions/profile';
import Spinner from '../layouts/Spinner';
import { Link, withRouter } from 'react-router-dom';
import DashboardActions from './DashboardActions';
import Experience from './Experience';
import Education from './Education';
import { deleteAccount } from '../../actions/profile';
const Dashboard = () => {
const dispatch = useDispatch(() => getCurrentUser(), () => deleteAccount());
const profileUser = useSelector(state => state.profile);
const auth = useSelector(state => state.auth);
const { profile, loading } = profileUser;
const { user } = auth;
useEffect(() => dispatch(getCurrentUser()), [dispatch]);
return loading && profile === null ? (
<Spinner />
) : (
<Fragment>
<h1 className="large text-primary">Dashboard</h1>
<p className="lead">
<i className="fa fa-user"></i>
{' '}Welcome {user && user.name}
</p>
{profile !== null ? (
<Fragment>
<DashboardActions />
<Experience experience={profile.experience} />
<Education education={profile.education} />
<div className="my-2">
<button
className="btn btn-danger"
onClick={() => dispatch(deleteAccount())}
>
Delete My Account!!!
</button>
</div>
</Fragment>
) : (
<Fragment>
<p>You have not yet setup profile, please add some info</p>
<Link to="/create-profile" className="btn btn-primary">
Create Profile
</Link>
</Fragment>
)}
</Fragment>
);
};
export default withRouter(Dashboard);
I am here to provide you About code that You need to know Kindly review this and Ans to get out this problems Thanks..

Resources