【问题标题】:React hook forms to watch fields on dynamic forms反应钩子表单以观察动态表单上的字段
【发布时间】:2022-01-21 22:50:49
【问题描述】:

我正在使用 react 钩子表单解决方案实现一个动态表单。表单是用来创建引用的,这样用户就可以添加任意多的行,并且在每一行中都必须告知:

  • 产品
  • 材质
  • 单位

完成这 3 个字段后,我们的 api 将返回该行的价格。

现在我已经设法在使用 handleSubmit 钩子提交时读取了表单值,但现在我正在尝试实现 watch 函数,所以每次每行上的三个输入之一被填充时,它都会检查另外两个和如果它们被填满,则到达 api 以获取线路价格。

除此之外,我想使用相同的功能来检查用户是否更新了产品、单位或材料,因此我应该重新计算线路价格。

在第一次渲染时,用户没有线条,当他单击按钮时,我用{} 填充数组并更新视图以添加新线条。

这是我正在使用的代码:

const [rows, setRows] = useState([]);
  const [year, setYear] = useState();
  const [generation, setGeneration] = useState();

  const newRowHandler = () => {
    setRows((prevState) => [...prevState, {}]);
  };
  const {
    register,
    handleSubmit,
    watch,
    formState: { errors },
  } = useForm();
  const onSubmit = (data) => {
    console.log(data.row);
    success();
  };

  const generations = [
    { value: 1, brand: "BMW", name: "BMW Serie 3 E70 3p" },
    { value: 2, brand: "BMW", name: "BMW Serie 3 E70 5p" },
    { value: 2, brand: "BMW", name: "BMW Serie 5 E72 5p" },
  ];

  const yearHandler = (event) => {
    setYear(event.target.value);
  };

  const generationHandler = (event) => setGeneration(event.target.value);

  console.log(watch()); // console.log del estado total del formulario cada vez que escribimos algo

  const watcher = (control, name) => {
    const value = watch(name);
  }

  return (
    <>
      <div className={classes.new__select_generation}>
        <div className={classes.new__select__generation_year}>
          <label>Año</label>
          <select name="year" onChange={yearHandler}>
            <option value="">--Selecciona un año--</option>
            <option value="2000">2000</option>
            <option value="2001">2001</option>
            <option value="2002">2002</option>
            <option value="2003">2003</option>
            <option value="2004">2004</option>
            <option value="2005">2005</option>
          </select>
        </div>
        <div className={classes.new__select__generation__name}>
          <label>Año</label>
          <select
            name="year"
            onChange={generationHandler}
            disabled={year ? false : true}>
            <option value="">--Selecciona una generación--</option>
            <option value="1">BMW Serie 3 E70 3p</option>
            <option value="2">BMW Serie 3 E70 5p</option>
            <option value="3">BMW Serie 5 E72 5p</option>
          </select>
        </div>
      </div>
      <div className={classes.new__buttons}>
        <button
          className={classes.new__buttons__add_row}
          onClick={newRowHandler}
          disabled={generation ? false : true}>
          Nueva fila
        </button>
      </div>
      <form onSubmit={handleSubmit(onSubmit)}>
        {rows?.length > 0 &&
          rows?.map((row, index) => {
            return (
              <div className={classes.new} key={index}>
                <div className={classes.new__row}>
                  <div className={classes.new__row__field}>
                    <label>Producto</label>
                    <input
                      type="text"
                      {...register(`row.${index}.product`)}
                      onChange={watcher(`row.${index}.product`)}
                    />
                  </div>
                  <div className={classes.new__row__field}>
                    <label>Material</label>
                    <input
                      type="text"
                      {...register(`row.${index}.material`)}
                      onChange={watcher(`row.${index}.material`)}
                    />
                  </div>
                  <div className={classes.new__row__field}>
                    <label>Unidades</label>
                    <input
                      type="number"
                      {...register(`row.${index}.units`)}
                      min="1"
                      onChange={watcher(`row.${index}.units`)}
                    />
                  </div>
                  <div className={classes.new__row__field}>
                    <label>Precio</label>
                    <input
                      type="number"
                      {...register(`row.${index}.price`)}
                      disabled
                    />
                  </div>
                </div>
                <div className={classes.new__separator}></div>
              </div>
            );
          })}
        <div className={classes.new__buttons}>
          {/* Quiza debería de ser un link */}
          <Link to="/quotes" style={{ textDecoration: "none", color: "black" }}>
            <FontAwesomeIcon icon={faAngleLeft} /> Volver al listado
          </Link>
          <button type="submit" disabled={rows.length > 0 ? false : true}>
            Guardar
          </button>
        </div>
      </form>
    </>
  );
};

我尝试在每个输入上使用 onChange 并调用一个函数来接收 watch 函数的输入,但它不起作用这是我尝试过的函数:

const linePriceHandler = (index) => {
    console.log(`line price handler`);
    console.log(`${watch(`${index}.product`)}`);
    console.log(`${watch(`${index}.material`)}`);
    console.log(`${watch(`${index}.units`)}`);
  };

这个想法是每次更新一个字段时,我都可以访问同一行上的所有字段。也许watch 函数不是合适的函数?

Link to the sandbox

【问题讨论】:

  • 你能提供一个codeandbox吗?
  • @Joris 我刚刚添加了问题的链接

标签: javascript reactjs react-hooks react-hook-form


【解决方案1】:

您可以尝试在输入更改时使用getValues()。因此,您将能够获取所有表单值并使用它。

https://react-hook-form.com/api/useform/getvalues

【讨论】:

    猜你喜欢
    • 2022-07-20
    • 2021-10-12
    • 1970-01-01
    • 1970-01-01
    • 2020-05-13
    • 1970-01-01
    • 2021-12-13
    • 1970-01-01
    • 2020-08-21
    相关资源
    最近更新 更多