reactjs React Hook窗体中的字段不会更新窗体状态,除非该字段获得焦点

n8ghc7c1  于 2023-02-18  发布在  React
关注(0)|答案(2)|浏览(153)

我正在使用React Hook Form。我有以下简单表单:
A simple form
当我在"quantity"和"price"字段中输入值时,第三个字段"total"显示了它们相乘的结果。到目前为止,一切正常。但我注意到,当我单击submit按钮时,"total"字段中的值不会更新数据表单,除非之前通过单击它获得了焦点。这是我没有单击"total"字段时得到的结果:
Showing the state form in the console
正如您在最后一幅图中看到的,"total"字段的值没有反映在表单状态中。
这是我的代码:

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

我期望表单状态更新,而不管"total"字段是否获得焦点。
提前感谢大家的帮助。

jaql4c8m

jaql4c8m1#

setValueuseEffect结合使用可能会更容易:

const { register, handleSubmit, 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
  />
tcomlyy6

tcomlyy62#

解决了,谢谢@Anurag Srivastava(抱歉我还不能投票),这是最终代码:

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

相关问题