Navigate the user to another URL using useNavigate() of react-router-dom-v6 [duplicate] - reactjs

This question already has answers here:
React Router Dom, useNavigate not redirecting to the right url path
(2 answers)
Closed yesterday.
I am working on a React 18 application and I am trying to navigate the guest user to the shipping page (URL: localhost:3000/shipping) from the cart page by clicking the Proceed to Checkout button. On clicking the button, the user should be first re-directed to the sign in page where he should sign in (on the SigninScreen page) and then proceed to the shipping page.
The current url when clicking the Proceed to Checkout button is (URL: localhost:3000/signin?redirect=shipping)
On clicking the SignIn button on the SignInScreen page I do a redirect in the useEffect() hook:
import { useSearchParams, useNavigate } from 'react-router-dom';
import { useDispatch, useSelector } from 'react-redux';
const userSignin = useSelector((state) => state.userSignin);
const { userInfo, loading, error } = userSignin;
const [searchParams] = useSearchParams();
const redirectUrl = searchParams.get('redirect') || '/';
const navigate = useNavigate();
useEffect(() => {
// If the user is logged in, the user should redirected to the shipping page.
if (userInfo) {
navigate(redirectUrl, {replace: true});
}
}, [userInfo, redirectUrl, navigate]);
Even after using {replace: true} the user does not get navigated to localhost:3000/shipping, instead it gets redirected to localhost:3000/signin/shipping
Could someone please guide me on what am I doing wrong?
Tried: Even after using {replace: true} the user does not get navigated to localhost:3000/shipping, instead it gets redirected to localhost:3000/signin/shipping
Expectation: The user should navigate to localhost:3000/shipping from localhost:3000/signin?redirect=shipping on signing the user in on the sign in screen by clicking the Sign In button

URLs which do not start with a / are treated as relative links to the current route. You are navigating the user to shipping when it should be /shipping.
Here’s one way to add the starting slash:
const redirectUrl = '/' + (searchParams.get('redirect') || '');

Related

facing issue in redirect user to home page react redux toolkit

Hello guys good day to you
I'm a beginner I'm facing one problem below screen shots I'm using redux toolkit with react Js problem is that I want when my user successfully login so its automatic redirect to home page for this I create a state in redux which name is_Login on successfully login I set my state to true and check if its true then user redirect to home its works but is_login state changes 6 times depends on other data coming so my page refresh 6 times how I can solve this??
main file
redux file
main file code
const { is_Login } = useSelector((state) => state);
const navigate = useNavigate();
const [checkIsLogin, setCheckIsLogin] = useState(false);
// if(is_Login){
// setCheckIsLogin(true)
// }
console.log('is_Login', is_Login)
const isLoginCheck = () => {
if (is_Login) {
setCheckIsLogin(true)
}
else {
console.log('not login')
}
}
useEffect(() => {
isLoginCheck()
return console.log('hello from effect')
}, [is_Login])
console.log('checkIsLogin', checkIsLogin)
I'm trying when user login its redirect to home page

Unable to set state in .then block after FireBase login with Facebook

I can't seem to figure out what I'm doing incorrectly. Whenever I'm clicking on my Sign In button, my UserContext state does not get set accordingly.
I'm trying to get it to set, and then navigate to the next page.
Any insight on how I can best approach this and why this is happening?
import { UserContext } from "../Components/UserContext";
import { signInWithPopup, FacebookAuthProvider } from "firebase/auth";
[...]
let navigate = useNavigate();
const { user, setUser } = useContext(UserContext);
// Login from Firebase
const signInWithFacebook = () => {
const provider = new FacebookAuthProvider()
signInWithPopup(authentication, provider)
.then((result) => {
const credential = FacebookAuthProvider.credentialFromResult(result);
token = credential.accessToken;
userB = result.user;
setUser(userB)
console.log(user) // this equals null
navigate("../home") // because user state = null, "Home" does not exist in my router, then goes to my 404 page.
})
}
[.......]
return (
[...]
<button onClick={signInWithFacebook}> Sign In </button>
[...]
)
I've tried await in some portions but it never assigned itself accordingly. Along with that I've also tried to set the setUser in a different function, and called that function. That still didn't work for me.

How to detect history change action (back, forward, etc) in react-router-dom v6?

All I could find concerning listening to the location change is a code like:
const location = useLocation();
useEffect(() => {}, [location]);
But the issue I'm trying to solve is to understand whether the user went back or forward on the page, which the location object doesn't provide by itself.
My business requirement is to log out the user when they press "back" and the "back" page was a log in page which successfully logged the user in. I solved flagging the location via location.state to understand whether it's a post-successful-login route. Now I want to listen to the "back" action in the browser and emit the logout flow based on location.state.
If you have a better solution I'm all ears.
If you only need to know how a user got to the current page then react-router-dom#6 has a useNavigationType hook that returns the type of navigation.
useNavigationType
declare function useNavigationType(): NavigationType;
type NavigationType = "POP" | "PUSH" | "REPLACE";
Example:
import { NavigationType, useNavigationType } from 'reat-router-dom';
...
const navigationType = useNavigationType();
...
switch (navigationType) {
case NavigationType.POP:
// back navigation
case NavigationType.PUSH:
// forward navigation
case NavigationType.REPLACE:
// redirection
default:
// ignore
}
Example:
import {
NavigationType,
useLocation,
useNavigationType.
} from 'reat-router-dom';
...
const navigationType = useNavigationType();
const location = useLocation();
useEffect(() => {
if (location.pathname === "/login" && navigationType === NavigationType.POP) {
// dispatch logout action
}
}, [location, navigationType]);
If you want to couple listening for navigation actions and calling a callback then consider something like this answer.

How to redirect user back to initially-requested page after authentication with React-Router v6?

I have a situation where, if a user isn't authenticated, they get redirected to the login page.
Once the user logs in, they get sent back to the main page.
This is a pretty typical situation with React, but I'm wondering how I can redirect the user back to a certain page after they authenticate.
Suppose the user tries to access /app/topics, which would be a private route. They would get redirected to /, where they have to authenticate. Afterwards, they get redirected to /app/about once they authenticated.
How can I ensure that the user gets redirected back to /app/topics instead?
The About component would look something like,
const About = ({ user }) => {
const navigate = useNavigate();
React.useEffect(() => {
if (!user) navigate("/");
}, [user]);
return (
<div>
<h2>About</h2>
</div>
);
};
export default About;
And Home (or the 'login page') would look like this,
const Home = ({ user, setUser }) => {
const navigate = useNavigate();
React.useEffect(() => {
if (user) navigate("/app/about");
}, [user]);
return (
<div>
<h2>Login</h2>
<input />
<button onClick={() => setUser(1)}>login</button>
</div>
);
};
export default Home;
I'm aware the this line,
if (user) navigate("/app/about");
Is why the user gets redirected to About upon authenticating, but I'm wondering how I can change this up, so that the user is redirected back to Topics.
I've tried a combination of different approached. The most promising thing that I've tried was saving the requested uri into my Redux state. This cause issue with my existing code, however.
I've also tried saving state with Navigate or useNavigate.
If I recall correctly, React-Router v5 had a redirect prop or something of the sort, that redirected the user back to a certain page.
I would just fallback to good old query parametr in url, just upon redirecting to login page, put query param, from or something in url, and upon successfull login do the redirect, this has the huge advatage that if you take him to different page or for some reason he has to reload page, he keeps this info.
React router v6 documentation provides an exemple that answers you requirements, here is their sandbox.
They use the from property of location's state:
function LoginPage() {
let navigate = useNavigate();
let location = useLocation();
let auth = useAuth();
let from = location.state?.from?.pathname || "/";
function handleSubmit(event: React.FormEvent<HTMLFormElement>) {
event.preventDefault();
let formData = new FormData(event.currentTarget);
let username = formData.get("username") as string;
auth.signin(username, () => {
// Send them back to the page they tried to visit when they were
// redirected to the login page. Use { replace: true } so we don't create
// another entry in the history stack for the login page. This means that
// when they get to the protected page and click the back button, they
// won't end up back on the login page, which is also really nice for the
// user experience.
navigate(from, { replace: true });
});
}

React redirection page with history.push give a bad url

I have a button and when press this button execute the function createEvent and this put in the page with url
mypage.com/event/create
If I press this again because is a component that I used in all page even in th create my url is:
mypage.com/event/event/create
and get error page not found
my function:
const history = useHistory();
const createEvent = () => {
history.push('event/create');
};

Resources