El uso del custom hook en React siempre invoca a la función.
He creado un hook personalizado en el cual una de las variables de estado obtiene el valor inicial de una función (ver el ejemplo a continuación). Cuando hago referencia al valor, se llama a la función y se devuelve el valor devuelto por la función en lugar del último valor almacenado.
En el ejemplo a continuación, el valor inicial de touched
es el valor devuelto por la función createDefaultValue
. En handleOnBlur
, estoy actualizando el valor de touched
. Cada vez que llamo a esta función, obtengo el valor predeterminado para touched
en lugar del último objeto actualizado.
const useForm = ({ initialValues = {} }) => {
const createDefaultValues = (defaultValue) =>
Object.keys(initialValues).reduce((obj, key) => {
obj[key] = defaultValue;
return obj;
}, {});
const [touched, setTouched] = React.useState(createDefaultValues(false));
React.useEffect(() => {
console.log(touched);
}, [touched]);
const handleOnBlur = async (e) => {
const { name } = e.target;
setTouched({ ...touched, [name]: true });
};
return { touched, handleOnBlur };
}
export default useForm;
Uso: en el archivo form.tsx
import useForm from './useForm';
const Form = (props) => {
const { touched, handleOnBlur } = useForm({
initialValues: { name: null, email: null }
});
return (
<>
<textfield id="name" helpertext="{touched.name" 'debe="" ser="" válido'="" :="" ''}="" error="{touched.name}" onblur="{handleOnBlur}" onchange="{..}" value="{..}"></textfield>
<textfield id="email" helpertext="{touched.email" 'debe="" ser="" válido'="" :="" ''}="" error="{touched.email}" onblur="{handleOnBlur}" onchange="{..}" value="{..}"></textfield>
)
}
export default Form;
davy.ai
El problema que estás enfrentando se debe a que la función
createDefaultValues
se llama cada vez que se vuelve a renderizar el componente, y por lo tanto, el valor inicial detouched
se sobrescribe con los valores predeterminados devueltos por la función. Para solucionar este problema, puedes envolver la funcióncreateDefaultValues
dentro del hookReact.useMemo
, que solo se llamará una vez durante el renderizado inicial y devolverá el valor en caché para renderizados posteriores.Aquí tienes una implementación actualizada del hook personalizado
useForm
:Observa cómo la función
createDefaultValues
está envuelta en el hookuseMemo
, que utilizainitialValues
como su dependencia. Esto asegura que la función solo se llame una vez durante el renderizado inicial y que se devuelva el valor en caché para renderizados posteriores.Además, la función
setTouched
se actualiza para usar la forma funcional que toma el estado anterior como argumento y devuelve el estado actualizado. Esto asegura que el estadotouched
anterior no se sobrescriba y que el nuevo valor se mezcle con el estado anterior.