admin管理员组

文章数量:1302318

I am using React Hook Form. I have this simple form:

A simple form

When I enter values in the "quantity "and "price" fields, the third field, "total" shows the result of multiplying them. So far, all fine. But I have noticed that when I click the submit button the value in the "total" field does not update the data form, unless that previously it get the focus by clicking on it. This is what I get when I don't click the "total" field:

Showing the state form in the console

As you can see in the last image, the value of the "total" field is not reflected in the form state.

This is my code:

import { useForm } from "react-hook-form"

function App() {

  const { register, handleSubmit, watch } = useForm({
    defaultValues: {
      price: 0,
      quantity: 0,
      total: 0
    }
  });

  const onSubmit = data => console.log(data)

  return (
    <div className="App">
      <form onSubmit={handleSubmit(onSubmit)}>

        <div>
          <label htmlFor="quantity">Quantity: </label>
          <input type="number" 
            {...register("quantity")}  
          />
        </div>

        <div>
          <label htmlFor="price">Price: </label>
          <input type="number"
            {...register("price")}
          />
        </div>
        
        {
          /** 'total' is the result of multiplying the two previous fields. 
          *   It only updates the form data when it get the focus.
          */
         }
        <div>
          <label htmlFor="total">Total: </label>
          <input type="number"
            {...register("total")}
            value={watch('price') * watch('quantity')}
            readOnly
          />
        </div>

        <input type="submit" value='Submit' />
      </form>
    </div>
  )
}

export default App

I was expecting the form state to update regardless of whether or not the "total" field got focus.

Thanks in advance everyone for your help.

I am using React Hook Form. I have this simple form:

A simple form

When I enter values in the "quantity "and "price" fields, the third field, "total" shows the result of multiplying them. So far, all fine. But I have noticed that when I click the submit button the value in the "total" field does not update the data form, unless that previously it get the focus by clicking on it. This is what I get when I don't click the "total" field:

Showing the state form in the console

As you can see in the last image, the value of the "total" field is not reflected in the form state.

This is my code:

import { useForm } from "react-hook-form"

function App() {

  const { register, handleSubmit, watch } = useForm({
    defaultValues: {
      price: 0,
      quantity: 0,
      total: 0
    }
  });

  const onSubmit = data => console.log(data)

  return (
    <div className="App">
      <form onSubmit={handleSubmit(onSubmit)}>

        <div>
          <label htmlFor="quantity">Quantity: </label>
          <input type="number" 
            {...register("quantity")}  
          />
        </div>

        <div>
          <label htmlFor="price">Price: </label>
          <input type="number"
            {...register("price")}
          />
        </div>
        
        {
          /** 'total' is the result of multiplying the two previous fields. 
          *   It only updates the form data when it get the focus.
          */
         }
        <div>
          <label htmlFor="total">Total: </label>
          <input type="number"
            {...register("total")}
            value={watch('price') * watch('quantity')}
            readOnly
          />
        </div>

        <input type="submit" value='Submit' />
      </form>
    </div>
  )
}

export default App

I was expecting the form state to update regardless of whether or not the "total" field got focus.

Thanks in advance everyone for your help.

Share edited Jul 13, 2023 at 14:30 Anurag Srivastava 14.4k4 gold badges36 silver badges45 bronze badges asked Feb 17, 2023 at 17:11 SANDRO SIMONSANDRO SIMON 611 gold badge1 silver badge6 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 4

Edit: You would need to watch the fields as well, to get their values in the app:

const price = watch("price") 
const quantity = watch("quantity")

It might be easier for you to use setValue bined with useEffect:

const { register, handleSubmit, watch, setValue } = useForm({ 
  defaultValues: { price: 0, quantity: 0, total: 0 } 
});

...

useEffect(() => {
  setValue('total', quantity * price)
}, [quantity, price])

...

  <input type="number"
    {...register("total")} // No need to watch        
    readOnly
  />

Solved. Thank you @Anurag Srivastava (sorry I'm not allowed to vote yet). This is the final code:

import { useEffect } from "react";
import { useForm } from "react-hook-form"

function App() {

  const { register, handleSubmit, setValue, watch } = useForm({
    defaultValues: {
      price: 0,
      quantity: 0,
      total: 0
    }
  });

  // I had to add these two lines
  const price = watch("price") 
  const quantity = watch("quantity")

  useEffect( ()=> {
    setValue('total', price * quantity)
  }, [price, quantity, setValue])

  const onSubmit = data => console.log(data)

  return (
    <div className="App">
      <form onSubmit={handleSubmit(onSubmit)}>

        <div>
          <label htmlFor="quantity">Quantity: </label>
          <input type="number" 
            {...register("quantity")}  
          />
        </div>

        <div>
          <label htmlFor="price">Price: </label>
          <input type="number"
            {...register("price")}
          />
        </div>
        
        {
          /** 'total' is the result of multiplying the two previous fields. 
          *   It only updates the form data when it get the focus.
          */
         }
        <div>
          <label htmlFor="total">Total: </label>
          <input type="number"
            {...register("total")}
            //value={watch('price') * watch('quantity')}
            readOnly
          />
        </div>

        <input type="submit" value='Submit' />
      </form>
    </div>
  )
}

export default App

本文标签: