Home > OS >  my state is not getting value into it REACT
my state is not getting value into it REACT

Time:11-11

I added two handlers to my code. First, mail is entered and handleStart is started, then the user name and password are obtained from the user, and then when the button is pressed, handleFinish is activated and information assignments are made. setEmail state works but password and name states do not

  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const [name, setName] = useState("");

  const history = useHistory();
  const url = "http://localhost:3002/register";

  const emailRef = useRef();
  const passwordRef = useRef();
  const usernameRef = useRef();

  const handleStart = () => {
        setEmail(emailRef.current.value);
      }
      const handleFinish = async (e) => {
        e.preventDefault();
        console.log("ref data", passwordRef.current.value,usernameRef.current.value) 
        //it works and shows values
        setPassword(passwordRef.current.value);
        setName(usernameRef.current.value);
        console.log("state data", email, password, name)
        //status values are empty except for email
        try {
          
          await axios.post(url, { email, name, password });
          history.push("/");
        } catch (err) { }
      }

and my return (HTML) codes:

 {!email ? (
          <div className="input">
            <input type="email" placeholder="email address" ref={emailRef} />
            <button className="registerButton" onClick={handleStart}>
              Get Started
            </button>
          </div>
        ) : (
          <form className="input">
            <input type="username" placeholder="username" ref={usernameRef} />
            <input type="password" placeholder="password" ref={passwordRef} />
            <button className="registerButton" onClick={handleFinish}>
              Start
            </button>
          </form>
        )}

CodePudding user response:

It's better to use useState to store and get values and control element rather then using ref.

Here is the code using state, that may help you:

const App = () => {
    const history = useHistory();
    const url = "http://localhost:3002/register";

    const [step, setStep] = useState(0)
    const [email, setEmail] = useState("")
    const [password, setPassword] = useState("")
    const [username, setUsername] = useState("")

    const handleStart = () => {
        setStep(1)
    }
    const handleFinish = async (e) => {
        e.preventDefault();
        console.log("data: ", email, password, username)
        try {
            await axios.post(url, { email, name, password });
            history.push("/");
        } catch (err) { }
    }

    return (
        step === 0 ? (
            <div className="input">
                <input
                    type="email"
                    value={email}
                    onChange={(e) => setEmail(e.target.value)}
                    placeholder="email address"
                />
                <button className="registerButton" onClick={handleStart}>
                    Get Started
                </button>
            </div>
        ) : (
            <form className="input">
                <input
                    type="username"
                    placeholder="username"
                    value={username}
                    onChange={(e) => setUsername(e.target.value)}
                />
                <input
                    type="password"
                    placeholder="password"
                    value={password}
                    onChange={() => setPassword(e.target.value)}
                />
                <button className="registerButton" onClick={handleFinish}>
                    Start
                </button>
            </form>
        )
    )
}

CodePudding user response:

This is very well known problem, explained thousands time here,
that state changes are internally asynchronous means we wont get updated state on next line immediately, it takes time to complete execution of setPassword and setName, so next line after set state, console.log would be old values

console.log(passwordRef.current.value)
console.log(usernameRef.current.value)

this must have values, and logged on console but not password and name this below behavior is correct, known and no issues here,

 console.log("state data", email, password, name)
 //status values are empty except for email

better would be, this below hack works always for me,

 await axios.post(url, { email, usernameRef.current.value, passwordRef.current.value });

CodePudding user response:

If you wish to do some activity based on value change for email, password, name using useEffect could be a better option. You can call API or perform any activity as an effect of those values change. Please find following code -

useEffect(() => {
    await axios.post(url, { email, name, password });
    history.push("/");
    return () => {
        // handle cancelling or other clean up
    }
}, [email, password, name]);
  • Related