Lullaby
Lullaby

Reputation: 119

React State being reset without explicitly saying so

I am making a small web app with react and firebase. My issue is that when the user logs in, the isLoggedIn state goes from null to true back to null and so Navigation bar cannot change to show that the user is logged in.

In App.js, I have cut quite a bit out for brevity:

class App extends Component {
 constructor(props) {
   super(props);
    this.state = {
     isLoggedIn: null
    };
  }

As you can see isLoggedIn = null is the original state that I want to be changed to true, if user login is successful

 componentDidMount() {
  auth.onAuthStateChanged((user) => {
  if (user) {
    this.setState({isLoggedIn: user.I})
  } 
 });
}

The above function in componentDidMount() is to handle the resetting of state if the page ever refreshes. It is a firebase function that supposedly fetches the last time the user was active and returns this state as a boolean value to whether the user is still logged in or not. Here, what I want it do is only set the state if the user is authenticated, if not, do nothing so that the user can log in.

handleLogIn = (e) => {
   e.preventDefault();
   auth.signInWithPopup(provider)
   .then((result) => {
     const isLoggedIn = result.user.I;
     this.setState({
      isLoggedIn: isLoggedIn
     });
   });
 }

This function allows the user to sign in via popup through Google which also returns a boolean value of whether the authentication was successful on that end or not, either way, I use this value to set the state.

render(props) {
  return (
    <div>
      <Navigation
       {...props}
        isLoggedIn={this.state.isLoggedIn}
        handleLogIn={this.handleLogIn}
       />
    )
   }
  export default App

Lastly, I'm passing, these functions to my Navigation.js which is a functional component that only takes props. It looks like so:

import React from "react";
import { Link } from "react-router-dom";

export default function Navigation (props) {
  console.log(props.isLoggedIn)
  return (
    <ul className="tabs tabs-transparent">
     <li className="tab">
       <Link to="/">Home</Link>
     </li>
     <li className="tab">
    <Link to="/all_stories">All 
     Stories</Link>
     </li>
     <li className="tab">
    <Link to="/story/create">Write A 
    Story</Link>
    </li>
    {props.isLoggedIn ? (
       <div>
        <li className="tab">
          <Link to="/user/:id/profile">Profile</Link>
         </li>

         <li className="tab">
           <Link to="/logout" onClick={props.handleLogOut()}>Log Out</Link>
            </li>
            </div>
              ) : (
          <li className="tab">
         <Link to="/all_stories" onClick={(e) => props.handleLogIn(e)}>Log In</Link>
                  </li>
              )}
       </ul>
     );
    };

When I try to console.log the changing of state as the user goes through the login process, it looks like so:

Null, Null, True, True, Null, Null

What I would like to know is why is changing back all of a sudden at the last moment?

  1. I originally thought it was the function occurring at the componentDidMount() but commenting that out had no effect
  2. Another reason I thought there was an error was possibly because I was using a functional component, where if the expression returns null or undefined it would keep that value as the origin one, I was wondering if I did an if statement for the function to wait a certain amount of time before it ran, that it would be able to grab the true state again.

Thank you in advance

Upvotes: 1

Views: 398

Answers (1)

Arkadii Berezkin
Arkadii Berezkin

Reputation: 268

Looks like that this behaviour is caused by this line:

<Link to="/logout" onClick={props.handleLogOut()}>Log Out</Link>

Because you're calling props.handleLogOut() in onClick instead of giving it a function to call. You should be doing something like onClick={props.handleLogOut} or onClick={() => props.handleLogOut()}.

Here's what happens in your case:

  1. You are not logged in. Thus Link to logout is not rendered and props.handleLogout is not called.
  2. You are logging in and props.isLoggedIn becomes true.
  3. Navigation component rerenders rendering this problematic Link.
  4. props.handleLogout called resetting user to null.

That's just a kind of a typo.

Upvotes: 1

Related Questions