Home > Back-end >  react using non managed attributes with managed attributes
react using non managed attributes with managed attributes

Time:11-28

Please refer my code below I wrote for just learning purpose :

import { useState } from "react";

function LoginForm() {

    const [username, setUsername] = useState("");
    const [password, setPassword] = useState("");


    let isInputTouched = false;

    const [isValidForm, setIsValidForm] = useState(false);

    function formSubmitHandler(event) {
        event.preventDefault();
        isInputTouched = true;
        if (username.length < 10 || password.length < 10) {
            setIsValidForm(false);

            console.log((!isValidForm && isInputTouched));
            setUsername("");
            setPassword("");
            return;
        }
    }

    function usernameHandler(event) {
        const inputValue = event.target.value;
        setUsername(inputValue);
        isInputTouched = true;
    }
    function passwordHandler(event) {
        const inputValue = event.target.value;
        setPassword(inputValue);
        isInputTouched = true;
    }

    return (
        <div className="container w-50 border shadow p-5">
            <form onSubmit={formSubmitHandler}>
                <div class="mb-3">
                    <label for="exampleInputEmail1" class="form-label">Email address</label>
                    <input onChange={usernameHandler} type="text" class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp" value={username} />
                    <div id="emailHelp" class="form-text">We'll never share your email with anyone else.</div>
                </div>
                <div class="mb-3">
                    <label for="exampleInputPassword1" class="form-label">Password</label>
                    <input onChange={passwordHandler} type="password" class="form-control" id="exampleInputPassword1" value={password} />
                </div>
                {(!isValidForm && isInputTouched) && < p className="text text-center text-danger">please enter valid email and password</p>}

                <button type="submit" class="btn btn-primary">Submit</button>
            </form>
        </div >
    );
}

export default LoginForm;

My current understanding is that if any of the attributes managed by useState are updated, the jsx will be re evaluated. If that is the case, when I hit a submit button without entering any input jsx reevaluation should happen because I am calling setIsValidForm() in that. Now since I am updating isInputTouched manually (isInputTouched = true;) in the line before so this value should be considered anywhere its value is asked for but it wont trigger the reevaluation of jsx, but that should happen when I call setIsValidForm(false);. And post that my error warning should pop up : {(!isValidForm && isInputTouched) && < p className="text text-center text-danger">please enter valid email and password

}. But thats not hapenning.

Please help me understand where am I going wrong.

Thanks

CodePudding user response:

Reason

This is happening because, the value of isInputTouched is not persisted across rerenders. Every time the component rerenders, the value of isInputTouched is reset to false.


Code

Here is an example to show, how the isInputTouched is erased on every rerender.

Note: Check the Browser's console for clarity.

Steps:

  1. Click on setRand button then see console (no extra logs as no rerender, but you are expecting randVar change)
  2. Click on ToggleValid button. There the value of randVar will be shown (in logs) before the state updation.
  3. After the state updation, a new table will appear in browser's logs due to rerender on state change. You will notice that, setRand is reset to false. Here is the gist

https://codesandbox.io/s/modest-bardeen-j6efc?file=/src/index.js


Solution

You can use useState for isInputTouched as well.

  • Related