【发布时间】: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 函数不是合适的函数?
【问题讨论】:
-
你能提供一个codeandbox吗?
-
@Joris 我刚刚添加了问题的链接
标签: javascript reactjs react-hooks react-hook-form