Estoy tratando de validar un formulario antes de enviarlo, y creé un objeto de posibles errores, pero cuando trato de cambiar el valor de cada clave, se comporta de manera extraña ...
const inialState = { name: "", email: "", message: "", }; const errors = { name: false, email: false, message: false, }; const Contact = () => { const [values, setValues] = useState(inialState); const [error, setError] = useState(errors); const handleSubmit = (e) => { e.preventDefault(); if (!validateSubmit()) { return; } }; const handleChange = (e) => setValues({ ...values, [e.target.name]: e.target.value }); function validateSubmit(e) { let response = true; if (!values.name) { setError({ ...error, name: true }); response = false; } if (!values.email) { setError({ ...error, email: true }); response = false; } if (!values.message) { setError({ ...error, [errors.message]: true });// I also tried this way =( response = false; } console.log(error); return response; } ... return( <form onSubmit={handleSubmit}> //its a simple button type="submit" ...La función validarEnviar es llamada por el botón Enviar.
La respuesta aquí es useReducer() para modificar solo partes del estado. https://reactjs.org/docs/hooks-reference.html#usereducer .
const errors = { name: false, email: false, message: false, }; const reducer = (state, action) => { return {...state, ...action}; }; const [error, updateError] = useReducer(reducer, errors ); function validateSubmit(e) { let response = true; if (!values.name) { updateError({name: true }); response = false; } if (!values.email) { updateError({email: true }); response = false; } if (!values.message) { updateError({message: true }); response = false; } return response; }El problema ocurre cuando llamas a setError varias veces desde validateSubmit . Solo ganará el último valor; en su ejemplo, ese es el que agregó "false": true (porque errors.message . mensaje que usó como nombre de propiedad es false ).
Tenga en cuenta que setError no actualiza (sincrónicamente o en absoluto) la constante de error , solo cambia el estado del componente y hace que se vuelva a representar con un nuevo valor. El {...errror, …} siempre se refirió al valor original de error . Para evitar esto, puede
agregue los errores en un solo valor antes de llamar a setError una vez
function validateSubmit(e) { let newError = error; if (!values.name) { newError = { ...newError, name: true }; } if (!values.email) { newError = { ...newError, email: true }; } if (!values.message) { newError = { ...newError, message: true }; } console.log(error, newError); setError(newError); return newError != error; } o use la versión de devolución de llamada de setError que ejecutará las actualizaciones en una fila y siempre pasará el último estado en cada devolución de llamada como argumento:
function validateSubmit(e) { let response = true; if (!values.name) { setError(oldError => ({ ...oldError, name: true })); response = false; } if (!values.email) { setError(oldError => ({ ...oldError, email: true })); response = false; } if (!values.message) { setError(oldError => ({ ...oldError, message: true })); response = false; } console.log(error); return response; }