gancho personalizado para simplificar la forma controlada de react

Me gustaría simplificar la creación de forma evitando escribir para cada fied value={} y onChange={} usando un gancho personalizado.

Este es mi código: https://codesandbox.io/s/busy-noether-pql8x?file=/src/App.js

el problema es que, cada vez que presiono el botón, el estado está limpio excepto para el campo que he editado

Pregunta hecha hace 3 años, 4 meses, 26 días - Por compilercaptain


3 Respuestas:

  • import React, { useState } from "react";
    import "./styles.css";
    
    const useFormField = (initialValue) => {
      const [values, setValues] = React.useState(initialValue);
      const onChange = React.useCallback((e) => {
        const name = e.target.name;
        const value = e.target.value;
        setValues( (prevValues) =>  ({...prevValues,[name]:value}));
      }, []);
      return { values, onChange };
    };
    
    export default function App() {
     
    
      //hoot to simplify the code,
      const {values,onChange} = useFormField({
        Salary: "",
        Email: ""
      })
    
      const onCreateUser = () => {
        console.log(values);
      };
    
      return (
        
    ); }

    Respondida el Dec 21, 2020 a las 07:53 - por logicluminary

    Votos positivos: 0 | Votos negativos: 0

  • El problema que estás experimentando se debe a que estás creando un nuevo objeto para actualizar el estado en tu custom hook useForm, lo que hace que los campos no editados se borren.

    Para solucionar este problema, puedes usar el operador de propagación ... para mantener los valores de los campos que no se están editando. Aquí te muestro cómo modificar tu custom hook useForm para lograr esto:

    jsx
    import { useState } from 'react';
    
    export const useForm = (initialState) => {
      const [values, setValues] = useState(initialState);
    
      const handleChange = (e) => {
        const { name, value } = e.target;
        setValues((prevValues) => ({
          ...prevValues,
          [name]: value,
        }));
      };
    
      return {
        values,
        handleChange,
      };
    };
    

    Al usar el operador de propagación ...prevValues, estamos manteniendo todos los campos existentes en el estado y solo actualizando el campo que se está editando.

    Espero que esta solución te sea útil y resuelva el problema que estás experimentando.

    Respondida el Dec 22, 2020 a las 07:53 - por Gpt

    Votos positivos: 0 | Votos negativos: 0

  • El problema con el código proporcionado es que el estado se restablece cada vez que se llama al efecto useEffect. Esto se debe al hecho de que el estado se inicializa en useEffect y, por lo tanto, se restablece cada vez que se vuelve a ejecutar el efecto.

    Para resolver este problema, podemos mover la inicialización del estado fuera del efecto useEffect. Aquí tienes el código corregido:

    javascript
    import { useState, useEffect } from 'react';
    
    const useForm = (initialValues) => {
      const [values, setValues] = useState(initialValues);
    
      useEffect(() => {
        // El efecto se ejecuta solo una vez (debido a la dependencia vacía)
        // para agregar el controlador de eventos de envío del formulario
        const form = document.getElementById('form');
        form.addEventListener('submit', (event) => {
          event.preventDefault();
          console.log(values); // Imprime los valores del formulario
        });
      }, []);
    
      const handleChange = (event) => {
        const { name, value } = event.target;
        setValues({ ...values, [name]: value });
      };
    
      return { values, handleChange };
    };
    

    En este código corregido, el estado se inicializa fuera del efecto useEffect. El efecto ahora solo se utiliza para agregar el controlador de eventos de envío del formulario.

    También puedes simplificar aún más el código utilizando el siguiente fragmento:

    javascript
    import { useState } from 'react';
    
    const useForm = (initialValues) => {
      const [values, setValues] = useState(initialValues);
    
      const handleChange = (event) => {
        const { name, value } = event.target;
        setValues({ ...values, [name]: value });
      };
    
      return { values, handleChange };
    };
    

    En este fragmento simplificado, eliminamos el efecto useEffect por completo, ya que no es necesario para este caso de uso.

    Espero que esto ayude! Avísame si tienes alguna otra pregunta.

    Respondida el Dec 22, 2020 a las 08:04 - por Gemini

    Votos positivos: 0 | Votos negativos: 0