[英]Maintain state of useFieldArray react-hook-form
我使用react-hook-form構建了一個多步表單,並使用 useFieldArray 構建了一個動態字段數組。
文檔: useFieldArray 文檔
這是完整的工作代碼鏈接: React Multi-step form with useFieldArray
在第二步中,當我使用添加狗按鈕添加新字段時,一切正常,使用小狀態機將步驟的新數據保存到本地存儲。
但是當我單擊上一個按鈕時,添加的字段消失了,而數據仍在本地存儲中。
第二步的代碼:
import { useForm, useFieldArray } from "react-hook-form";
import { useStateMachine } from "little-state-machine";
import updateAction from "./updateAction";
import { useNavigate } from "react-router-dom";
function Step2(props) {
const {
register,
control,
handleSubmit,
watch,
formState: { errors },
} = useForm({
defaultValues: {
test: [{ nameOfDog: "Bill", ageOfDog: "2", sizeOfDog: "small" }],
},
});
const { fields, append, remove } = useFieldArray({
control,
shouldUnregister: true,
name: "test",
});
const elements = watch("test");
console.log(elements, fields);
const { actions, state } = useStateMachine({ updateAction });
const navigate = useNavigate();
const onSubmit = (data) => {
// console.log(fields);
actions.updateAction(data);
navigate("/step3");
};
let dta;
if (state.date2) {
dta = new Date(state.date2);
} else {
dta = new Date();
dta.setDate(dta.getDate() + 1);
}
return (
<form className="form" onSubmit={handleSubmit(onSubmit)}>
<div className="stepn stepn-active" data-step="1">
{fields.map((item, index) => {
return (
<div className="row" key={item.id}>
<div className="col">
<label htmlFor="nameOfDog">Name:</label>
<input
id="nameOfDog"
{...register(`test.${index}.nameOfDog`, {
required: true,
})}
defaultValue={item.nameOfDog}
/>
{errors.nameOfDog && (
<span>This field is required</span>
)}
</div>
<div className="col">
<label htmlFor="ageOfDog">Age:</label>
<input
id="ageOfDog"
type="number"
{...register(`test.${index}.ageOfDog`, {
required: true,
})}
defaultValue={item.ageOfDog}
/>
{errors.ageOfDog && (
<span>This field is required</span>
)}
</div>
<div className="col">
<label htmlFor="sizeOfDog">Size in Lbs:</label>
<select
id="sizeOfDog"
{...register(`test.${index}.sizeOfDog`, {
required: true,
})}
defaultValue={item.sizeOfDog || ""}
>
<option value="small">Small (40)</option>
<option value="large">Large (40+)</option>
</select>
{errors.sizeOfDog && (
<span>Please Select an option</span>
)}
</div>
<div className="col">
<button
onClick={(e) => {
e.preventDefault();
remove(index);
}}
style={{ padding: "26px 62px" }}
>
Delete
</button>
</div>
</div>
);
})}
<div className="row">
<div className="col">
<button
onClick={(e) => {
e.preventDefault();
append({
nameOfDog: "Bill2",
ageOfDog: "5",
sizeOfDog: "large",
});
}}
>
Add a Dog
</button>
</div>
</div>
</div>
{/* <input type="submit" /> */}
<div className="row">
<button className="prev" onClick={() => navigate("/")}>
Previous
</button>
<button className="next">Next</button>
</div>
</form>
);
}
export default Step2;
{fields.map((item, index) =>
每當單擊上一個按鈕時,字段數組都會重置為默認值。
當我們回到上一步時,除了第 2 步之外,表格的所有其余步驟都將被保存。
當我單擊上一個按鈕時,如何保存第二步中的字段。
這里有兩個問題:
<form />
元素中移動handleSubmit
並將其傳遞給您的兩個<button />
元素。 這樣您就可以擺脫 watch 調用,因為您在 handleSubmit 回調中有當前的表單數據。const onPrevious = (data) => {
actions.updateAction(data);
navigate("/");
};
const onNext = (data) => {
actions.updateAction(data);
navigate("/step3");
};
<div className="row">
<button className="prev" onClick={handleSubmit(onPrevious)}>
Previous
</button>
<button className="next" onClick={handleSubmit(onNext)}>
Next
</button>
</div>
如果您想在<form />
元素中保留handleSubmit
,您應該使用 watch 並將數據傳遞到您的狀態機,然后再導航回上一步。
const test = watch("test");
const onPrevious = (data) => {
actions.updateAction({ test });
navigate("/");
};
defaultValues
useForm
給每個步驟的useForm
。 對於“第 2 步”,它看起來像這樣:const {
register,
control,
handleSubmit,
watch,
formState: { errors }
} = useForm({
defaultValues: {
test: state.test ?? [
{ nameOfDog: "Bill", ageOfDog: "2", sizeOfDog: "small" }
]
}
});
需要更改的重要一點是,當您在useForm
配置中為您的字段傳遞defaultValues
時,您應該將其從<Controller />
組件中刪除。 我為“第 1 步”做的,所以你有一個例子。
它很長,但也許我們可以弄清楚。
使用是正確的,我認為問題在於您沒有檢查狀態並且每次都打印默認值
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.