Tengo una página simple con campos de entrada y un botón y quiero desactivar el botón cuando la longitud de ambos campos es inferior a 3. Es algo simple, pero estoy confundido acerca del gancho porque entra en un bucle infinito. Aquí está el código:
function TableFooterPanel(props) { const [firstName, setFirstName] = useState(''); const [lastName, setLastName] = useState(''); // const [isButtonDisabled, setIsButtonDisabled] = useState(true); const addNewCustomer = async (name, surname) => { await service.addCustomer(name, surname); props.funcParam(); } var isButtonDisabled = false; if (firstName <= 3 || lastName <= 3) { isButtonDisabled = true; } else { isButtonDisabled = false; } return ( <> <Card className='buttonFooter'> <Form className='buttonFooter'> <input type="text" placeholder="First Name" defaultValue={firstName} onChange={e => setFirstName(e.target.value)}></input> <input type="text" placeholder="Last Name" defaultValue={lastName} onChange={e => setLastName(e.target.value)}></input> <Button disabled={isButtonDisabled} onClick={() => addNewCustomer(firstName, lastName)}>Add</Button> </Form> </Card> </> ); } export default TableFooterPanel;Con este código, las casillas solo marcan si están vacías o llenas.
Si elimino el comentario useState hook y trato de configurarlo en la condición if-else, entonces esta vez está ocurriendo un bucle infinito y la página se bloquea.
¿Cómo puedo verificar la longitud de entrada sin caer en un bucle infinito?
Probar :
if (firstName.length <= 3 || lastName.length <= 3) { isButtonDisabled = true; } else { isButtonDisabled = false; }Le sugiero que no escriba código directamente en el cuerpo del componente: no sabe cuántas veces se ejecutará ese código. Mucho mejor usa un gancho useEffect :
function TableFooterPanel(props) { const [firstName, setFirstName] = useState(''); const [lastName, setLastName] = useState(''); const [isButtonDisabled, setIsButtonDisabled] = useState(true); const addNewCustomer = async (name, surname) => { await service.addCustomer(name, surname); props.funcParam(); } useEffect(() => { if (firstName.length <= 3 || lastName.length <= 3) { setIsButtonDisabled(true); } else { setIsButtonDisabled(false); } }, [firstName, lastName]); return ( <> <Card className='buttonFooter'> <Form className='buttonFooter'> <input type="text" placeholder="First Name" defaultValue={firstName} onChange={e => setFirstName(e.target.value)}></input> <input type="text" placeholder="Last Name" defaultValue={lastName} onChange={e => setLastName(e.target.value)}></input> <Button disabled={isButtonDisabled} onClick={() => addNewCustomer(firstName, lastName)}>Add</Button> </Form> </Card> </> ); } export default TableFooterPanel; Como puede ver, he usado un gancho useEffect con firstName y lastName en la lista de deps: esto significa que, cada vez que firstName o lastName cambien, useEffect se activará.
Y no olvide eso, para verificar la longitud de la cadena, debe usar la propiedad de length =).
Aquí tienes: demostración de Codesandbox
Simplemente podría agregar el argumento deshabilitado en línea de esta manera:
<button disabled={firstName.length < 3 || lastName.length < 3} onClick={() => addNewCustomer(firstName, lastName)} > Add </button>