主要问题是您有条件地呈现表单,因此所有以前的表单值都被删除。解决方案是保持所有表单都已安装,并根据选择的表单使用display: none 或display: block。这样,每当您转到下一个或上一个表单或提交表单时,所有值都将保持不变。
第二个问题是您在卸载时没有删除密码字段,因此当调用 moveToNext 时,triggerValidation 回调中的 valid 参数始终为 false。我通过根据密码输入是否可见有条件地设置 Form1 的字段来解决此问题。
您将defaultValues 用于错误目的的第三个问题。您可以使用getValues() 获取当前表单值,这将返回表单的所有当前值。
我将uname字段的默认值设置为一个示例,向您展示如何使用defaultValues。
您可以在此处查看完整的解决方案:https://codesandbox.io/s/fragrant-forest-75pzs?file=/src/App.js
这里是所有更改的文件:
App.js
import React, { useState } from "react";
import Form1 from "./components/Form1";
import Form2 from "./components/Form2";
import Form3 from "./components/Form3";
import { useForm } from "react-hook-form";
function MainComponent() {
const {
register,
triggerValidation,
defaultValues,
errors,
getValues
} = useForm({
// You can set default values here
defaultValues: {
uname: "Lol"
}
});
console.log("Errors: ", errors);
const [currentForm, setCurrentForm] = useState(0);
// control password input visibility and Form1 fields
const [passwordVisible, setPasswordVisible] = useState(false);
const showPassword = () => {
setPasswordVisible(true);
};
const hidePassword = () => {
setPasswordVisible(false);
};
const forms = [
{
fields: passwordVisible
? ["uname", "email", "password"]
: ["uname", "email"],
component: (register, errors) => (
<Form1
// a key is needed to render a list
key={0}
// this will be used to set the css display property to block or none on each form
shouldDisplay={currentForm === 0}
register={register}
errors={errors}
showPassword={showPassword}
hidePassword={hidePassword}
passwordVisible={passwordVisible}
/>
)
},
{
fields: ["lname"],
component: (register, errors) => (
<Form2
key={1}
shouldDisplay={currentForm === 1}
register={register}
errors={errors}
/>
)
},
{
component: (register, errors) => (
<Form3
key={2}
shouldDisplay={currentForm === 2}
register={register}
errors={errors}
values={getValues()}
/>
)
}
];
const moveToPrevious = () => {
triggerValidation(forms[currentForm].fields).then(valid => {
if (valid) setCurrentForm(currentForm - 1);
});
};
const moveToNext = () => {
triggerValidation(forms[currentForm].fields).then(valid => {
if (valid) setCurrentForm(currentForm + 1);
});
};
const prevButton = currentForm !== 0;
const nextButton = currentForm !== forms.length - 1;
const handleSubmit = e => {
console.log("whole form data - ", getValues());
};
return (
<div>
<div className="progress">
<div>{currentForm}</div>
</div>
{forms.map(form => form.component(register, errors))}
{prevButton && (
<button
className="btn btn-primary"
type="button"
onClick={moveToPrevious}
>
back
</button>
)}
{nextButton && (
<button className="btn btn-primary" type="button" onClick={moveToNext}>
next
</button>
)}
{currentForm === 2 && (
<button
onClick={handleSubmit}
className="btn btn-primary"
type="submit"
>
Submit
</button>
)}
</div>
);
}
export default MainComponent;
表格1
import React from "react";
function Form1({
register,
errors,
shouldDisplay,
passwordVisible,
showPassword,
hidePassword
}) {
return (
<div style={{ display: shouldDisplay ? "block" : "none" }}>
<form autoComplete="on">
<br />
<div className="form-group">
<label>User name</label>
<input type="text" name="uname" ref={register({ required: true })} />
{errors.uname && <span>required</span>}
<label>Email</label>
<input type="email" name="email" ref={register({ required: true })} />
{errors.email && <span>required</span>}
</div>
<div>
<div className="col-12 col-sm-12 col-md-12 col-lg-12 col-xl-12">
<label className="form_label">Password</label>
<div className="form-check">
<label>
<input
type="radio"
name="auto_pass"
id="Radios1"
value="auto_pass"
className="form-check-input"
defaultChecked={true}
onChange={hidePassword}
/>
Auto generated password
</label>
</div>
<div className="form-check">
<label>
<input
type="radio"
name="auto_pass"
id="Radios2"
value="let_me"
className="form-check-input"
onChange={showPassword}
/>
Let me create the password
</label>
</div>
</div>
{passwordVisible && (
<div className="col-12 col-sm-12 col-md-12 col-lg-12 col-xl-12 mb-3">
<label className="form_label">Password</label>
<input
type="password"
name="password"
className="form-control"
ref={register({ required: true })}
/>
{errors.password && (
<span className="text-danger">Password is reguired</span>
)}
</div>
)}
</div>
</form>
</div>
);
}
export default Form1;
Form2
import React from "react";
function Form2({ register, errors, shouldDisplay }) {
return (
<div style={{ display: shouldDisplay ? "block" : "none" }}>
<form autoComplete="on">
<br />
<div className="form-group">
<label>User last name</label>
<input type="text" name="lname" ref={register({ required: true })} />
{errors.lname && <span>required</span>}
</div>
</form>
</div>
);
}
export default Form2;
Form3
import React from "react";
function Form3({ values, shouldDisplay }) {
return (
<div style={{ display: shouldDisplay ? "block" : "none" }}>
<h3>Want to display all values here like below</h3>
{Object.entries(values).map(([key, value]) => (
<p key={key}>
{key}: {value}
</p>
))}
<br />
<p>So that use can check for any Wrong info</p>
</div>
);
}
export default Form3;