Skip to content
Advertisement

TypeError: setEmail is not a function onChange

Trying to create sign in and sign up with react and firebase and got the error setEmail is not a function when trying to fill the input for the email, if i try to fill the input for password, i get the same error but for setPassword setPassword is not a function App.js

import React, { useState, useEffect } from "react";
import fire from './fire';
import LogIn from './LogIn';
import Hero from './Hero';
import './App.css';

const App = () => {
  const {user, setUser} = useState('');
  const {email, setEmail} = useState('');
  const {password, setPassword} = useState('');
  const {emailError, setEmailError} = useState('');
  const {passwordError, setPasswordError} = useState('');
  const {hasAccount, setHasAccount} = useState(false);

const clearInputs = () => {
  setEmail('');
  setPassword('');
}

const clearErrors = () => {
  setEmailError('');
  setPasswordError('');
}

const handleLogin = () => {
  clearErrors();
  fire
    .auth()
    .signInWithEmailAndPassword(email, password)
    .catch((err) => {
      switch(err.code){
        case "auth/invalid-email":
        case "auth/user-disabled":
        case "auth/user-not-found":
          setEmailError(err.message);
          break;
        case "auth/wrong-password":
          setPasswordError(err.message);
          break;
      }
    });
};

const handleSignup = () => {
  clearErrors();
  fire
    .auth()
    .createUserWithEmailAndPassword(email, password)
    .catch((err) => {
      switch(err.code){
        case "auth/email-already-in-use":
        case "auth/invalid-email":
          setEmailError(err.message);
          break;
        case "auth/weak-password":
          setPasswordError(err.message);
          break;
      }
    });
}

const handleLogout = () => {
  fire.auth().signOut();
};

const authListener = () => {
  fire.auth().onAuthStateChanged((user) => {
    if (user) {
      clearInputs();
      setUser(user);
    } else {
      setUser("");
    }
  });
};

useEffect(() =>{
  authListener();
}, [])

  return (
    <div className="App">
      {user ? (
        <Hero handleLogout={handleLogout} />
      ) : (
      <LogIn 
        email={email} 
        setEmail={setEmail} 
        password={password} 
        setPassword={setPassword} 
        handleLogin={handleLogin}
        handleSignup={handleSignup}
        hasAccount={hasAccount}
        setHasAccount={setHasAccount}
        emailError={emailError}
        passwordError={passwordError}
      />
      )
    }
    </div>
  );
};

export default App;

and the code for LogIn.js

import React from 'react';

const LogIn = (props) => {

    const {
    email,
    setEmail, 
    password,
    setPassword,
    handleLogin,
    handleSignup,
    hasAccount,
    setHasAccount,
    emailError,
    passwordError
    } = props;

    return(
        <section className="login">
            <div className="loginContainer">
                <label>Username</label>
                <input type="text" 
                    autoFocus 
                    required 
                    value={email}
                    onChange={(e) => setEmail(e.target.value)} 
                />
                <p className="errorMsg">{emailError}</p>
                <label>Password</label>
                <input type="password" 
                    autoFocus 
                    required 
                    value={password} 
                    onChange={(e) => setPassword(e.target.value)} 
                />
                <p className="errorMsg">{passwordError}</p>
                <div className="btnContainer">
                    {hasAccount ? (
                        <>
                        <button onClick={handleLogin}>Sign In</button>
                        <p>Don't have an account? <span onClick={() => setHasAccount(!hasAccount)}>Sign UP</span></p>
                        </>
                    ) : (
                        <>
                        <button onClick={handleSignup}>Sign Up</button>
                        <p>Already Have an account? <span onClick={() => setHasAccount(!hasAccount)}>Sign In</span></p>
                        </>
                    )}
                </div>
            </div>
        </section>
    )
}
export default LogIn;

I’ve tried the solution for the same question that i’ve found here, but didn’t work for me as the code is slightly different. I’m just learning React so the answer maybe obvious.

Advertisement

Answer

You should change this:

const {email, setEmail} = useState('');

For this:

const [email, setEmail] = useState('');

Do it with every state declaration from useState hook as it returns an array and not an object

Advertisement