I am following a course in that course instructor wrote
react router dom version 5
const checkoutHandler = () => {
history.push('/login?redirect=shipping')
}
the above code is working fine in that course video,he is logging in and redirecting to shipping page
now i am using version 6 i changed above code to, i am unable to redirect to shipping
import {useNavigate} from 'react-router-dom';
const navigate=useNavigate();
const checkoutHandler=()=>{
navigate('/login?redirect=shipping')
}
and i can't understand what this '/login?navigate=shipping' command is doing exactly, why i am not able to rdirect.
MRE
App.js
<Routes>
<Route path='/cart' element={<CartScreen/>}/>
<Route path='/login' element={<LoginScreen/>}/>
<Route path='/shipping' element={<ShippingScreen/>}/>
<Route path='/' element={<HomeScreen/>} exact/>
</Routes>
CartScreen , Click on Checkout.
const checkoutHandler=()=>{
navigate('/login?navigate=shipping')
}
Takes you to Login page Fill in Form Hit Login login screen
const redirect = location.search ?
location.search.split('=')[1] : '/'
useEffect(() => {
if (localStorage.getItem('userInfo') !== null) {
navigate(redirect)
}
}, [])
isSuccess && navigate('/')
The issue is that react-router-dom@6
is capable of both absolute and relative path routing. The difference is that absolute paths start with a leading "/"
character while relative paths do not.
The redirect target is "shipping"
since the queryString is "?redirect=shipping"
navigate('/login?redirect=shipping');
In the LoginScreen
component the code is accessing the location.searchand getting the
"shipping"` value and attempting to navigate there.
const redirect = location.search ? location.search.split('=')[1] : '/'
useEffect(() => {
if (localStorage.getItem('userInfo') !== null) {
navigate(redirect); // <-- navigate("shipping")
}
}, []);
The result of this is a relative navigation from the current route path "/login"
to "/login/shipping"
since the leading "/"
is missing.
Use the useSearchParams
hook to access the queryString (instead of the "hackish" string manipulation), and navigate correctly to the "/shipping"
route.
Example:
import { useNavigate, useSearchParams } from 'react-router-dom';
...
const navigate = useNavigate();
const [searchParams] = useSearchParams();
const redirect = searchParams.get("redirect");
useEffect(() => {
if (JSON.parse(localStorage.getItem('userInfo'))) {
navigate(`/${redirect}`); // <-- navigate("/shipping")
}
}, [redirect]);