skip to Main Content

In the input I bind its value to the React.useState() value={state}. but for some reason, when submitting, data always contains the original value, even if the state has changed. However, the input itself sees the change in the state. But it works ok when value of the input changed manually

export default function App() {
  const {register, handleSubmit} = useForm()
  const [state, setState] = useState(1)
  const onSubmit = (data) => {
    console.log(data.input)  // always 1
  }
 
  return (
    <>
      <form action='' onSubmit={handleSubmit(onSubmit)}>
        <input type='text' {...register('input')} value={state} 
        onChange={(e) => setState(e.target.value)}/>
        <button type='button' onClick={() => setState(state + 1)}>
          increase
          </button>
          <button>submit</button>
      </form>
    </>
  );
}

when I click on increase button, and click sumbit button, it logs 1, however the value of input changes.

I expect that it logs the value of input

2

Answers


  1. The problem you are experiencing is caused by the way you are using the useState hook in combination with the value attribute of the component.

    When you set the value={state} attribute on the component, you are assigning the initial value of state to the input field. However, once the user interacts with the input field and changes its value manually, the internal state is updated correctly by the setState function, but the value attribute of the component is still bound to the original value of state.

    You can remove the value attribute from the component and rely on internal state to keep the value updated:

    export default function App() {
      const { register, handleSubmit } = useForm();
      const [state, setState] = useState(1);
    
      const onSubmit = (data) => {
        console.log(data.input); 
      };  
    
      return (
        <>
         <form action="" onSubmit={handleSubmit(onSubmit)}>
         <input type="text" {...register('input')} onChange={(e) => 
          setState(e.target.value)} />
         <button type="button" onClick={() => setState(state + 1)}>
           increase
         </button>
         <button type="submit">submit</button>
         </form>
        </>
      );
    }
    
    Login or Signup to reply.
  2. Use the setValue function from the useForm hook to change the form value for the input field.

    function App() {
    
      const {register, handleSubmit, setValue} = useForm();
      const [state, setState] = useState(1);
      const onSubmit = (data) => {
        console.log(data.input)
      }
    
      useEffect(() => {
        setValue('input', state);
      }, [state])
    
    
      return (
        <div className="App">
          <form action='' onSubmit={handleSubmit(onSubmit)}>
            <input type='text' {...register('input')} value={state} onChange={(e) => setState(parseInt(e.target.value))}/>
            <button type='button' onClick={() => setState(state + 1)}>
              increase
            </button>
            <button>submit</button>
          </form>
        </div>
      );
    }
    

    Note: I also changed the onChange to use parseInt, it has nothing to do with you problem, but once you changed the value in the input with the keyboard – it turned it to a string and then when clicking increase – it was concatinating the string instead of adding the number.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search