I am unable to disable submit button when someone signs up on my webpage.
import styles, {layout} from '../style';
import {eye, eye_hidden, google} from "../assets";
import {useState, useRef} from 'react';
import {useAuth} from '../contexts/AuthContext';
const SignUp = () => {
const {signup, currentUser} = useAuth()
const nameRef = useRef()
const emailRef = useRef()
const emailConfRef = useRef()
const pwRef = useRef()
const pwConfRef = useRef()
const [error, setError] = useState("")
const [loading, setLoading] = useState(false)
const [visibility_pw, setVisibility_pw] = useState(false)
const [visibility_pwConf, setVisibility_pwConf] = useState(false)
const handleVisibility = param => event => {
param === "pw" ? setVisibility_pw(!visibility_pw) : setVisibility_pwConf(!visibility_pwConf)
}
async function handleSubmit(event) {
event.preventDefault()
if (pwRef.current.value !== pwConfRef.current.value) {
return setError('Passwords or Emails do not match. Please try again.')
}
if (emailRef.current.value !== emailConfRef.current.value) {
return setError('Emails do not match!')
}
try {
setError('')
setLoading(true)
signup(emailRef.current.value, pwRef.current.value)
} catch(error) {
console.log(error.message)
setError('Unable to create account. Please try again')
}
setLoading(false)
}
return (
<div className={`${layout.sectionCenter} min-h-screen`}>
<div className="bg-black/25 shadow-xl shadow-[#8F6E5D]/40 rounded-2xl p-5 min-h-full xs:w-full max-w-[800px]">
<h2 className={`text-center mt-8 ${styles.heading4}`}>Create A New Account</h2>
{error &&
<div className="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative mx-8 mt-8" role="alert">
<strong className="block sm:inline font-bold">{error}</strong>
</div>}
{currentUser && currentUser.email}
<form action="" onSubmit={handleSubmit} className="flex flex-col px-8 gap-8 mt-12">
<input required type="text" name="name" id="name" ref={nameRef} placeholder="Enter Full Name" className="pl-2 py-2.5 rounded-lg border border-[#8F6E5D] border-opacity-75 bg-primary text-secondary" />
<input required type="email" name="email" id="email" ref={emailRef} placeholder="Enter Email" className="pl-2 py-2.5 rounded-lg border border-[#8F6E5D] border-opacity-75 bg-primary text-secondary" />
<input required type="email" name="email_conf" id="email_conf" ref={emailConfRef} placeholder="Confirm Email" className="pl-2 py-2.5 rounded-lg border border-[#8F6E5D] border-opacity-75 bg-primary text-secondary" />
<div className="relative">
<input required type={visibility_pw ? "text" : "password"} name="password" id="password" ref={pwRef} placeholder="Enter Password" className="pl-2 py-2.5 rounded-lg border border-[#8F6E5D] border-opacity-75 bg-primary w-full text-secondary" />
<img onClick={handleVisibility("pw")} src={visibility_pw ? eye_hidden : eye} alt="toggle password visibility" className={`${visibility_pw ? "h-[20px]" : "h-[65%]"} pw_visibility absolute top-[50%] right-5 -translate-y-[50%] cursor-pointer`} />
</div>
<div className="relative">
<input required type={visibility_pwConf ? "text" : "password"} name="password_conf" id="password_conf" ref={pwConfRef} placeholder="Confirm Password" className="pl-2 py-2.5 rounded-lg border border-[#8F6E5D] border-opacity-75 bg-primary w-full text-secondary" />
<img onClick={handleVisibility("pw_conf")} src={visibility_pwConf ? eye_hidden : eye} alt="toggle confirm password visibility" className={`${visibility_pwConf ? "h-[20px]" : "h-[65%]"} pw_visibility absolute top-[50%] right-5 -translate-y-[50%] cursor-pointer`} />
</div>
<button disabled={loading} type="submit" className={`py-2 px-6 font-playfairDisplay font-medium text-[18px] outline-none rounded-lg ${loading ? "bg-gradient-to-r from-[#8F6E5D]/50 to-[#7E4F43]/50 text-dimWhite/50" : "bg-gradient-to-r from-[#8F6E5D] to-[#7E4F43] text-white"} ${loading ? "" : styles.buttonHover} mx-auto mt-4`}>Sign Up</button>
</form>
<div className="mt-12 grid grid-cols-3 px-8 items-center">
<hr className="opacity-25"/>
<p className={`${styles.paragraph} text-center text-md`}>OR</p>
<hr className="opacity-25"/>
</div>
<button type="button" className="bg-white border py-2 px-4 mt-8 mb-12 mx-auto rounded-lg flex justify-center items-center text-center hover:scale-95 duration-300">
<img src={google} alt="google icon" className="h-[32px] w-[32px]" />
<p className="ml-3">Sign up with Google</p>
</button>
<div className="flex justify-between px-8 mt-4 mb-8">
<p className={`${styles.paragraph} text-sm sm:text-lg`}>Have an account?</p>
<button type="button" className="hover:scale-90 duration-300 hover:text-[#8F6E5D] hover:from-[#FAF6F5] hover:to-[#FAF6F5] hover:ease-in-out cursor-pointer py-1 px-2 bg-gradient-to-r from-[#8F6E5D] to-[#7E4F43] font-playfairDisplay font-medium text-[18px] text-white outline-none rounded-lg">Login</button>
</div>
</div>
</div>
)
}
export default SignUp
Under the button, disabled={loading}
does not work. I was however able to give an illusion of button being disabled when I created a const isDisabled=true
and used it in the button like the following:
<button disabled={loading} type="submit" className={`py-2 px-6 font-playfairDisplay font-medium text-[18px] outline-none rounded-lg ${isDisabled ? "bg-gradient-to-r from-[#8F6E5D]/50 to-[#7E4F43]/50 text-dimWhite/50" : "bg-gradient-to-r from-[#8F6E5D] to-[#7E4F43] text-white"} ${isDisabled ? "" : styles.buttonHover} mx-auto mt-4`}>Sign Up</button>
However, the style is still not exactly dynamic as when I click on the submit the button still does not become disabled, as it keeps to the original value of isDisabled.
I cannot understand what is missing as I have tried various methods.
2
Answers
I think you are not using
await
insignup(emailRef.current.value, pwRef.current.value)
.and because you are not using await isLoading set true and immediately false.
Correct Code :
let me know if it work
It is not working as expected because you used
setLoading(false)
right after the catch body and the state after the code is completly runs so it is just setting the false again in order to fix this issue use thefinnaly
like:hopfully it will fix your issue