Home > Blockchain >  how to use multiple ref in my react input
how to use multiple ref in my react input

Time:05-03

hello guys pls i have a challenge in my react app, i am trying to enable multiple choice login where a user can either use his mail or even hi username to login. i got it working from my server using postman but when i try it on my frontend it doesnt allow me to use multiple refs on it, i am only allowed to use either the username or email. Here is my code

function Login() {
  const password = useRef();
  const email = useRef();
  const username = useRef();

  const { isFetching, dispatch } = useContext(AuthContext);

  const handleClick = (e) => {
    e.preventDefault();
    try {
      loginCall(
        {
          username: username.current.value,
          email: email.current.value,
          password: password.current.value,
        },
        dispatch
      );
    } catch (err) {
      console.log(err.response);
    }
  };
  return (
    <>
      <div className="log__bg">
        <div className="login">
          <div className="loginWrapper">
            <div className="loginLeft">
              <span className="loginDesc">Welcome Back</span>
              <ToastContainer />
            </div>

            <div className="loginRight">
              <form className="loginBox" onSubmit={handleClick} >
                <input
                  placeholder="Email, phone, or username"
                  type="text"
                  required
                  className="loginInput"
                  ref={username}
                />
                <input
                  placeholder="Password"
                  type="password"
                  required
                  minLength="6"
                  className="loginInput"
                  ref={password}
                />
                <button
                  className="loginButton"
                  type="submit"
                  disabled={isFetching}
                >
                  {isFetching ? (
                    <CircularProgress color="white" size="20px" />
                  ) : (
                    "Log In"
                  )}
                </button>

                <Link id="auth_route" to="/register">
                  <button className="loginRegButton">
                    {isFetching ? (
                      <CircularProgress color="white" size="20px" />
                    ) : (
                      "Create a New Account"
                    )}
                  </button>
                </Link>

                <div className="forgot__password">
                  <Link className="forgot__password__btn" to="/forgot-password">
                    Forgot Password?
                  </Link>
                </div>
              </form>
            </div>
          </div>
        </div>
      </div>
    </>
  );
}

export default Login;

CodePudding user response:

Why you need 2 refs ? user will provide username or email in the same input field. Use just one ref than you can have a logic or regex in your backend to detect if the provided value is an email or a username:

  const handleClick = (e) => {
    e.preventDefault();
    let username = null
    let email = null
    const emailRegex = /^\S @\S \.\S $/
    const inputValue = username.current.value

    if(inputValue.match(emailRegex)){
      email = inputValue
    } else {
      username = inputValue
    }
    
    try {
      loginCall(
        {
          username: username,
          email: email,
          password: password.current.value,
        },
        dispatch
      );
    } catch (err) {
      console.log(err.response);
    }
  };

With this if the user provided an email, username will be sent as null to the server and vice versa. Then you can check on the server if you get an email or a username.

UPDATE: You can also just use a state and don't use ref at all:

  const [usernameValue, setUsernameValue]=React.useState("")
  const [passwordValue, setPasswordValue]=React.useState("")

  const handleClick = (e) => {
    e.preventDefault();
    let username = null
    let email = null
    const emailRegex = /^\S @\S \.\S $/

    if(usernameValue.match(emailRegex)){
      email = inputValue
    } else {
      username = inputValue
    }
    
    try {
      loginCall(
        {
          username: username,
          email: email,
          password: passwordValue,
        },
        dispatch
      );
    } catch (err) {
      console.log(err.response);
    }
  };


  return (
    ...
            <form className="loginBox" onSubmit={handleClick} >
                <input
                  placeholder="Email, phone, or username"
                  type="text"
                  required
                  className="loginInput"
                  value={usernameValue}
                  onChange={e=>setUsernameValue(e.target.value)}
                />
                <input
                  placeholder="Password"
                  type="password"
                  required
                  minLength="6"
                  className="loginInput"
                  value={passwordValue}
                  onChange={e=>setPasswordValue(e.target.value)}
                />
    ...
    ...

  )

CodePudding user response:

I agree with @PatersonCode, the best way would be to use React.useState and just one variable to store your input value.

You didn't mention what error you're getting, but here's an example that I hope might help you in some way:

https://codesandbox.io/s/choose-login-method-example-xgpfue?file=/src/Login.js

  • Related