React dialog: Cannot read property 'state' of undefined
Tags: react
Published: 2020-11-01 19:16:17

For my application I have put in place protected routers where the user needs to log in. Here is the code for the login:

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">
        <form onSubmit={this.login} className="loginForm">
          <label>
            <span>Username</span>
            <input
              name="lUsername"
              type="text"
              placeholder="Enter your username"
              minLength="5"
              required
              onChange={this.handleInput} />
          </label>
          <label>
            <span>Password</span>
            <input
              name="lPassword"
              type="password"
              placeholder="Enter your password"
              minLength="5"
              required
              onChange={this.handleInput}
            />
          </label>
          <button type="submit" value="submit">Login</button>
        </form>
      </div>
    );
  }
}

export default Login;
```
Now I'm trying to replace this form by a material UI form dialog. Basically the user will be sent to the same component (login.jsx) when he starts the application. But the form will only appear when the user open the dialog. To do that I have made the following changes.

Dialog.js:
```
export default function FormDialog() {
    const [open, setOpen] = React.useState(false);

    const handleClickOpen = () => {
        setOpen(true);
    };

    const handleClose = () => {
        setOpen(false);
    };

    return (
        <div>
            <Button onClick={handleClickOpen}>
                Open form dialog
      </Button>
            <Dialog open={open} onClose={handleClose}>
                <DialogTitle>Login</DialogTitle>
                <DialogContent>
                    <label>
                        <span>Username</span>
                        <input
                            name="lUsername"
                            type="text"
                            placeholder="Enter your username"
                            minLength="5"
                            required
                            onChange={handleInput} />
                    </label>
                    <label>
                        <span>Password</span>
                        <input
                            name="lPassword"
                            type="password"
                            placeholder="Enter your password"
                            minLength="5"
                            required
                            onChange={handleInput}
                        />
                    </label>
                </DialogContent>
                <DialogActions>
                    <Button onClick={handleClose} color="primary">
                        Cancel
          </Button>
                    <Button onClick={login} color="primary">
                        Login
          </Button>
                </DialogActions>
            </Dialog>
        </div>
    );
}
```
Login.jsx:
```
class Login extends Component {
  constructor(props) {
    super(props);
this.handleInput = this.handleInput.bind(this);
this.login = this.login.bind(this);
    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 />
      </div>
    );
  }
}

export default Login;

export const 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();
};

export const handleInput = event => {
  let loginSettingsNew = { ...this.state.loginSettings };
  let val = event.target.value;
  loginSettingsNew[event.target.name] = val;
  this.setState({
    loginSettings: loginSettingsNew
  });
};
```
The dialog button and the form dialog appear, but I have the following error when I open the dialog:

Type error: Cannot read property 'state' of undefined


Most similar questions on StackOverflow say to bind the functions, but it didn't work :/. So I would like to ask some help please.

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