Tameiki
Tameiki

Reputation: 45

Form dialog don't set state

I have created a simple login function where once the user log in, he is redirect to another page. Then I wanted to change the login form with a form dialog. And the problem is here. The login dialog works, but when I enter the username and password, I'm not send to another page but to the same login page :/.

Here is the code:

Login.jsx:

class Login extends Component {
  constructor(props) {
    super(props);
    this.state = {
      islogged: false,
      loginSettings: {
        lUsername: "",
        lPassword: ""
      }
    };
  }

  handleInput = (event) => {
    let loginSettingsNew = { ...this.state.loginSettings };
    let val = event.target.value;
    loginSettingsNew[event.target.name] = val;
    this.setState({
      loginSettings: loginSettingsNew
    });
  };

  login = (event) => {
    let lUsername = this.state.loginSettings.lUsername;
    let lPassword = this.state.loginSettings.lPassword;
    if (lUsername === "admin" && lPassword === "password") {
      localStorage.setItem("token", "T");
      this.setState({
        islogged: true
      });
    } else {
      console.log("Erreur");
    }
    event.preventDefault();
  };

  render() {
    if (localStorage.getItem("token")) {
      return <Redirect to="/" />;
    }
    return (
      <div className="Login">
        <Dialog handleInput={this.handleInput} login={this.login} />
        <p>Username: admin - Password: password</p>
      </div>
    );
  }
}

Dialog.js:

export default function FormDialog() {
  const [open, setOpen] = React.useState(false);
  const handleClickOpen = () => {
    setOpen(true);
  };
  const handleClose = () => {
    setOpen(false);
  };
  return (
    <div>
      <Button variant="outlined" color="primary" onClick={handleClickOpen}>
        Open form dialog
      </Button>
      <Dialog open={open} onClose={handleClose}>
        <DialogTitle>Login</DialogTitle>
        <DialogContent>
          <form onSubmit={this.login}>
            <label>
              <span>Username</span>
              <input name="lUsername" type="text" onChange={this.handleInput} />
            </label>
            <label>
              <span>Password</span>
              <input name="lPassword" type="password" onChange={this.handleInput}/>
            </label>
            <Button onClick={handleClose} color="primary">Cancel</Button>
            <Button type="submit" value="submit" color="primary">Login</Button>
          </form>
        </DialogContent>
      </Dialog>
    </div>
  );
}

I also have created a sandbox of my code: https://codesandbox.io/s/react-login-auth-forked-r06ht

I thinks that the problem come from the form dialog that can't set the state of islogged of the login function. I tried quite a lot of things but nothing worked, so I would like to ask some help please.

I thank in advance anyone who will take the time to help me .

Upvotes: 0

Views: 150

Answers (2)

Elhassan Abdelhafez
Elhassan Abdelhafez

Reputation: 84

Ok all fixed. In your App.js you didn't have a home component to redirect to with this path="/". I've created a new component called home.js. Tidied the Routes for you.

<Route path="/login" component={Login} />
<ProtectedRoute path="/dashboard" component={Dashboard} />
<Route exact path="/" component={Home} />

Please check ur code sandbox https://codesandbox.io/s/react-login-auth-forked-24m8e?file=/src/App.js

Upvotes: 1

Robin Zigmond
Robin Zigmond

Reputation: 18249

I notice that your Login component is a class, while the child FormDialog component is a function component using Hooks. There's nothing wrong with that, in itself - particularly if you started with an application using all class components and are slowly converting your components. But I detect some confusion here, because your function component seems to assume it's a class, in a sense. When you need to do things a bit differently.

Specifically, you reference this.login in your function component - but this is meaningless. login is passed in as a prop. In a class component, you would reference it as this.props.login. This doesn't work in a function component - but this.login isn't the substitute. Indeed this will tend to be undefined so this would even give an error. Even if not, it's not correct.

All you need to do is to make use of the argument to your function component - this is where the props object "lives" in a function component. You happen to ignore it by not using any arguments - but you don't have to do this.

So in short, what you need to do is:

  1. replace export default function FormDialog() with export default function FormDialog(props)

  2. replace this.login with props.login

  3. repeat 2) for all other props which you have referenced using this

Upvotes: 3

Related Questions