How to dynamically update the value for any input field with one event handler function, using hooks

Thanks to Doğancan Arabacı. I tried to mimic the state and setState from class-based component so the feel doesn't change. My solution looks like this.

const [state , setState] = useState({
    email : "",
    password : ""
})

const handleChange = e => {
    const {name , value} = e.target
    setState( prevState => ({
        ...prevState,
        [name] : value
    }))
}

You should use setState with callback function:

setState(prev => ({ 
    ...prev,
    email: 'new mail',
}))

You'll create a new state object, which was created by previous state. And you can override anything you need. You'd need more new objects if you'd have a complex state object.


You could create a custom hook like so:

import { useState } from 'react';

export const useForm = (initialValues) => {
  const [values, setValues] = useState(initialValues);

  return {
    values,
    handleChange: (e) => {
      setValues({
        ...values,
        [e.target.name]: e.target.value,
      });
    },
    reset: () => setValues(initialValues),
  };
};

Then use it in any form (for example):

export default function SignInForm() {
    const { values, handleChange, reset } = useForm({ username: '', password: '' });

    const handleSubmit = e => {
        e.preventDefault();
        reset();
    };

    return (
        <form onSubmit={handleSubmit}>
            <input
                type='text'
                name='username'
                placeholder='Enter your username...'
                onChange={handleChange}
                value={values.username}
            />
            <input
                type='password'
                name='password'
                placeholder='Enter your password...'
                onChange={handleChange}
                value={values.password}
            />
            <button type='submit'>
                Sign In
            </button>
        </form>
    );
}