In older React Router Dom versions I was able to use this code to redirect if user is logged in:
history.push('/login?redirect=shipping')
Now in v6 I am using the useNavigate functions instead of history.push but it's not working as it is taking me to /login/shipping instead of /shipping. Currently this is my navigate code:
let navigateCart = useNavigate()
// some code here
navigateCart('/login?redirect=shipping') // the mistake is inside the parenthesis here but i dont know what it is!
This is my router config:
<BrowserRouter>
<Container>
<Routes>
<Route path="/" element={<HomeScreen />} exact />
<Route path="/login" element={<LoginScreen />} />
<Route path="/profile" element={<ProfileScreen />} />
<Route path="/shipping" element={<ShippingScreen />} />
</Routes>
</Container>
</BrowserRouter>
Login Screen Function :
function LoginScreen() {
let navigateLog = useNavigate()
let location = useLocation()
const [email, setEmail] = useState('')
const [password, setPassword] = useState('')
const dispatch = useDispatch()
const redirect = location.search ? location.search.split('=')[1] : '/'
const userLogin = useSelector(state => state.userLogin)
const { error, loading, userInfo } = userLogin
useEffect(() => {
if (userInfo) {
navigateLog(redirect)
}
}, [navigateLog, userInfo, redirect])
const submitHandler = (e) => {
e.preventDefault()
dispatch(login(email, password))
}
Change this line navigateLog(redirect) inside that useEffect in LoginScreen to this one:
navigateLog(`/${redirect}`);
In your case it's redirecting to /login/shipping instead of /shipping, cause it's like you are calling navigateLog("shipping") since redirect is equal to "shipping", so it's used as a relative path. Which means it takes into account your current url, which is in your case /login.
Here is a working CodeSandbox of a simplified version of your code as well.
The redirect target path is "shipping" instead of "/shipping". In react-router-dom@6 there are relative paths and absolute paths. The difference is simple, absolute paths start with a leading "/" character while relative paths do not. navigate("shipping") will append "shipping" to the end of the current pathname and navigate there.
Either prepend the leading "/" when navigating:
navigate(`/${navigateLog}`, { replace: true });
Or include it when you initially navigate:
navigateCart('/login?redirect=/shipping');
You'll likely also want to use the useSearchParams hook to access the redirect query parameter instead of relying on it to be at a specific string position.
function LoginScreen() {
const navigateLog = useNavigate();
const [searchParams] = useSearchParams();
...
const redirect = searchParams.get("redirect") || '/';
...
useEffect(() => {
if (userInfo) {
navigateLog(redirect, { redirect: true });
}
}, [navigateLog, userInfo, redirect])
...
Note that in issuing the imperative redirect that I've included an options object to the navigate function that specifies replace: true, this is to issue a REPLACE action instead of a PUSH action.