¿Cómo controlo una entrada vacía?
Estoy creando mi primer componente en React y tengo problemas con la lógica de cómo controlar o detectar cuando una entrada está vacía.
La idea es cambiar la clase de la entrada de acuerdo a su contenido, es decir
Si la entrada no está vacía, cambie el color del borde a verde. Si la entrada está vacía, cambie el color del borde a gris.
la logica funciona cuando la entrada tiene un texto, el problema es cuando borro el contenido la entrada no hace nada, hasta que vuelvo a escribir una letra me sale el mensaje "la entrada esta vacia" y se activa "la entrada con datos"
¿Por qué?
const { useEffect, useState } = React; const Login = function () { const [formState, setformState] = useState({ isActive: true, inputEmail: "", }); const { isActive, inputEmail } = formState; useEffect( function () { // console.log("hello"); }, [inputEmail] ); const handleInputChange = function (e) { if (inputEmail == "") { console.log("input is empty"); setformState({ ...formState, [e.target.name]: e.target.value, isActive: false }); } else { setformState({ ...formState, [e.target.name]: e.target.value, isActive: true }); console.log("input with data"); } }; return ( <input type="text" name="inputEmail" className={`inputClass ${isActive ? "inputSelected" : ""}`} autoComplete="off" onChange={handleInputChange} /> ); }; ReactDOM.render(<Login />, document.getElementById('root')); <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script> <div id="root"></div>Debería verificar el valor entrante que es e.target.value
const handleInputChange = function (e) { if (e.target.value == "") {//<-- console.log("input is empty"); setformState({ ...formState, [e.target.name]: e.target.value, isActive: false }); } else { setformState({ ...formState, [e.target.name]: e.target.value, isActive: true }); console.log("input with data"); } };Está utilizando el último valor de estado para su lógica, por lo que parece que siempre está un paso por detrás.
También debe establecer por defecto que su estado para isActive sea falso, ya que el valor de entrada es inicialmente falso.
En su lugar, use el nuevo valor ubicado en e.target.value como se muestra a continuación:
Cambié el estilo para que esté en línea y el color para afectar el fondo para una demostración más clara.
const { useEffect, useState } = React; const Login = function () { const [formState, setformState] = useState({ isActive: false, inputEmail: "", }); const { isActive, inputEmail } = formState; const handleInputChange = function (e) { if (e.target.value == "") { console.log("input is empty"); setformState({ ...formState, [e.target.name]: e.target.value, isActive: false }); } else { setformState({ ...formState, [e.target.name]: e.target.value, isActive: true }); console.log("input with data"); } }; return ( <input type="text" name="inputEmail" style={{ backgroundColor: isActive ? "green" : ""}} autoComplete="off" onChange={handleInputChange} /> ); }; ReactDOM.render(<Login />, document.getElementById('root')); <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script> <div id="root"></div>Dependiendo de sus requisitos, puede simplificar esto significativamente.
Si isActive siempre debe reflejar si inputEmail está vacío o no, entonces puede omitirlo del estado y determinarlo en cada procesamiento.
Esto significa que no necesita una condición en handleInputChange y puede actualizarla de la misma manera sin importar qué.
También recomendaría establecer explícitamente el accesorio de value de entrada en lugar de simplemente confiar en que permanezcan sincronizados.
const { useEffect, useState } = React; const Login = function () { const [formState, setformState] = useState({ inputEmail: "", }); const { inputEmail } = formState; const handleInputChange = function (e) { setformState({ ...formState, [e.target.name]: e.target.value }); }; return ( <input type="text" name="inputEmail" value={inputEmail} style={{ backgroundColor: !!inputEmail ? "green" : ""}} autoComplete="off" onChange={handleInputChange} /> ); }; ReactDOM.render(<Login />, document.getElementById('root')); <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script> <div id="root"></div>