How to prevent to visit login page if user is logged in - reactjs

How can I prevent to visit login page if user is logged in, I don't want to show user login page if user if user is not logged out. but I have tried with few step but it is not working for me.
I am storing static value in localstorage and if user try to come back into page login page then there I have created a function that user can visit to login page or not
login.js
componentWillMount(){
var id = localstorage.getitem('id')
if(id == "1"){
return <Redirect to="/dashboard"/>
}
}
Here I am able to get it and it going inside if condition as well but not redirecting to dashboard
I don't know what I am doing wrong here.
Your help would be highly appreciated
Thanks in Advance

Redirect works only when it is rendered, which means it is inside render or one of the functions called by it.
Returning a Redirect inside componentDidMount does not redirect the user. For use inside componentDidMount, you can use the imperative API:
this.props.history.push("/dashboard");
Docs for history
Note that this works only if the component is directly rendered inside a Route, otherwise props history will not be present. In other case, you can use withRouter higher order component.

Related

Protect routes react router dom 6

I have a route ('profile/edit') that edits some information, and I want to prevent the user from reaching it by typing in the URL. For example, I want if the user types www.mywebsite.com/profile/edit/ in the URL, it will get redirected to www.mywebsite.com/. So I only want it to be accessible when you click the edit button. How do I do this? I'm using react route 6 for this project.
Is this URL accessible only if logged in?
Or do you need any param values to edit?
If yes, please double check your implementation, there you have other best methods to do it
Answer
Call a useNavigate in one of your root component (inside useEffect which only call once)
//rootComponent
const navigate = useNavigate()
useEffect(()=> {
navigate('/')
), [])
//Rest of your code

React Route - On click check if user is logged in, if not, send him to login and then back to page

What I have at the moment:
User checks out leaderboard with a list of players.
User clicks on player card inside the leaderboard.
I check if User is logged in, if User is not logged in, I send him
to the Log In page.
What I desire.
User checks out leaderboard with a list of players.
User clicks on player card inside the leaderboard.
I check if User is logged in, if User is not logged in, I send him
to the Log In page, after he logs in, I send him back to the player profile he clicked earlier.
I literally have no idea how and where should I look for this.
I'm not sure if you are using any routers as you didn't specify that.
But what you need is called "Guarded Route" or "Route Guard".
A guard is a "check" or "condition" which will allow the user to visit a specified route or not.
Let me give you an example with React-Router.
https://codepen.io/najt/pen/jOBjOMW
in short you can do something like this:
const GuardedRoute = ({loggedIn, ...props}) => {
if (loggedIn) {
return <Route {...props} />;
}
return <Redirect to="/login" />
}
In a normal flow you should not allow someone to choose a profile if he is not logged in. And make sure that he has access to the selection only if he has already logged in. This is more UX (User Experience) than code but worth mentioning i think.
But if you really need the functionality you can look into "History" related to React-Router-Dom. It gives you the ability to retrieve the history of accessed URI and redirect back the user back to the page he tried to access.
Another possibility is redirect him onto Login with a param in the url &redirect=/profile/example and use this param during Login action.
With:
React#17
React-Router-Dom#5

Better way to update react component on event

I'm making a web-app in which I use React, together with Firebase Authentication. I have a login page and I want it to redirect to a different page when a user is already signed in.
To check if the user is logged in I use a method to retrieve the User object, it returns null when a user is not signed in and a user object with all sorts of data if they are.
I have an if statement in my render method (of the login page) which checks if the user is logged in, but I ran into an issue. When a user first loads up the page it takes around half a second for the Firebase API to retrieve the user object and until that is completed my user object will return null.
This makes for an issue where it seems as though my user isn't logged in even if they are. That causes them not to redirect and stay on the login page until the state is updated in some way after the user object is initialized.
Firebase offers a way to fix this by giving us an onAuthStateChanged() method which allows me to execute a function when a user signs in or logs out.
What I'm doing now is using this method in the constructor method of my Login page class to manually re-render the component, thus redirecting the user when Firebase logs them in. It looks something like this:
export default class Login extends React.Component<Props, State> {
constructor(props:Props) {
super(props)
this.props.firebase.auth().onAuthStateChanged((user) => {
const oldState = this.state
this.setState(oldState)
})
}
render () {
if (this.props.firebase.auth().currentUser) {
return (
<Redirect to="/earn" />
)
} else {
return (
// Login page
)
}
}
}
(I omitted some irrelevant code)
Now this works fine and all but I'm not sure if this is the correct way to do it and I feel like I could make it look a lot nicer, I just don't know how.
Any suggestions or official ways to achieve what I'm doing right now are very much appreciated.

How to wait for information (currentUser) before componentDidMount

I have a user profile page, when I refresh the page my redux store clears and then I have a fetch all the information again from the backend... but my profile page begins to mount before I get that information back.
I this function in my "loggedInRoutes.js". It will get the currentUser from the JWT token I have in localStorage, and save the userName and ID, etc, in my Redux Store
componentDidMount(){
if (localStorage.length===0){
this.props.history.push('/')
}else{
this.props.dispatchCurrentUser()
}
}
It's in the top level of my routes, the switch statement with my route rendering is in the same page.
In my profile page. (I need to check if the currentUser is friends with the user who's profile I went to, that's why I need both infos from the start).
componentDidMount(){
this.props.fetchProfile(this.props.currentUser, this.props.match.params.userId)
this.requestFriendshipFunction()
}
This works if I already have the currentUser in my redux store, but if I do a page refresh while on the profile page, the componentDidMount in the profile page gets called before I have that information, even though I'm calling the "dispatchCurrentUser" in a more container/parent component "loggedInRoutes".
Saving the currentUser info in local storage seems like a bad idea, and I'm not sure where to go from here.
Thank you.

React Router Dom Prevent Prompt When Params Change

I am building a React Redux application and I am using <Prompt/> from react-router-dom to prevent a user from navigating away from a page when a specific icon is being rendered on the page.
It works fine except for when the params in the url change and then it fires the <Prompt/> when I don't want it to fire because I haven't actually tried to navigate anywhere. My url looks like:
http://localhost:8080/#/path/im/on?ids=1%2C24&from=1512518400000&searchRequest=e0007&to=1512604799000
When the ids in the url become successful, they are removed from the url but <Prompt/> is still fired.
Is there any way I can prevent <Prompt/> from firing when the url params change and the first part of the url stays the same? i.e. http://localhost:8080/#/path/im/on
Not sure if this is still relevant to you but you can do the following:
'message' prop in the Prompt component can either be a string or a function that returns a string or boolean.
<Prompt
message={(location) => {
return location.pathname.startsWith("your url")
? true
: `Are you sure you want to go to ${location.pathname}?`
}}
/>
if a function is passed to message prop then it will be called with the next location and action the user is attempting to navigate to. Return a string to show a prompt to the user or true to allow the transition.
here is the documentation link: https://github.com/ReactTraining/react-router/blob/master/packages/react-router/docs/api/Prompt.md

Resources