Javascript 如何使用react以多步骤形式进行验证
我正在处理一个场景,在这个场景中,我必须完成一个我已经完成的多步骤表单,以及验证部分。我正在使用Javascript 如何使用react以多步骤形式进行验证,javascript,reactjs,react-hooks,react-hook-form,Javascript,Reactjs,React Hooks,React Hook Form,我正在处理一个场景,在这个场景中,我必须完成一个我已经完成的多步骤表单,以及验证部分。我正在使用react hook表单进行验证 我有多步骤表格: 在第一种形式中,我有几个字段和一个单选按钮 默认情况下,自动生成通行证的单选按钮被勾选,因此在这种情况下,我无事可做 第二个是让我创建一个密码,因此在这种情况下,将显示一个输入字段,用户将创建密码 问题 在我的最终表格中,我正在进行如下验证: { fields: ["uname", "email", &
react hook表单
进行验证
我有多步骤表格:
- 在第一种形式中,我有几个字段和一个单选按钮
- 默认情况下,
自动生成通行证的单选按钮被勾选,因此在这种情况下,我无事可做
- 第二个是
,因此在这种情况下,将显示一个输入字段,用户将创建密码让我创建一个密码
{
fields: ["uname", "email", "password"], //to support multiple fields form
component: (register, errors, defaultValues) => (
<Form1
register={register}
errors={errors}
defaultValues={defaultValues}
/>
)
},
{
字段:[“uname”、“email”、“password”],//支持多字段表单
组件:(寄存器、错误、默认值)=>(
)
},
因此,为了验证uname、email和密码,我将传递上述值
但是,当单选按钮勾选自动生成密码时,它仍在处理验证,我单击next,它不会转到next for,因为password字段
如果我选中单选按钮作为让我创建密码
,它将进入下一个表单,当我通过单击返回
返回时,它将再次进入自动生成的密码
,并且它不保持以前的状态。对于其他输入字段,它将处理以前的值,但单选按钮情况下不会处理
答案1原因是您的
字段:[“uname”、“email”、“password”]
是固定的,密码总是要进行验证。
解决方案需要在应用程序中存储表单1的状态
,以便您可以检查自动生成密码
的状态是否处于从列表中删除密码状态
App.js
... other code
// need to move state and function form Form to app
const [show_input, setshow_input] = useState(false);
const createInput = () => {
setshow_input(true);
};
const auto_text = () => {
setshow_input(false);
};
const forms = [
{
// validate based on show_input state
fields: show_input ? ["uname", "email", "password"] : ["uname", "email"], //to support multiple fields form
component: (register, errors, defaultValues) => (
<Form1
register={register}
errors={errors}
defaultValues={defaultValues}
auto_text={auto_text}
createInput={createInput}
show_input={show_input}
/>
)
},
{
fields: ["lname"],
component: (register, errors, defaultValues) => (
<Form2
register={register}
errors={errors}
defaultValues={defaultValues}
/>
)
},
{
component: (register, errors, defaultValues) => (
<Form3
register={register}
errors={errors}
defaultValues={defaultValues}
/>
)
}
];
... other code
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;
。。。其他代码
//需要将状态和功能表单移动到应用程序
const[show_input,setshow_input]=useState(false);
常量createInput=()=>{
设置SHOW_输入(真);
};
常量自动_文本=()=>{
设置SHOW_输入(假);
};
常数形式=[
{
//基于show_输入状态进行验证
字段:显示输入?[“uname”、“email”、“password”]:[“uname”、“email”],//支持多字段表单
组件:(寄存器、错误、默认值)=>(
)
},
{
字段:[“lname”],
组件:(寄存器、错误、默认值)=>(
)
},
{
组件:(寄存器、错误、默认值)=>(
)
}
];
... 其他代码
回答2下一步时,将卸载表单1
,因此其状态将被销毁。当您将Form1的状态存储在App.js中时,您也将修复此问题
好处:它更喜欢使用camalCase(例如:showInput)而不是下划线(show_input)
主要问题是有条件地呈现表单,以便删除所有以前的表单值。解决方案是保持所有窗体都已装入,只需根据选择的窗体使用display:none
或display:block
。这样,每当您转到下一个或上一个表单或提交表单时,所有值都将保持不变
第二个问题是,您在卸载密码字段时没有将其删除,因此当调用moveToNext
时,triggervalization
回调中的valid
参数始终为false。我修复了这个问题,根据密码输入是否可见,有条件地设置Form1的字段
第三个问题是,您使用defaultValues
的目的不正确。您可以使用getValues()
获取当前表单值,它将返回表单的所有当前值
我为uname
字段设置了默认值,只是作为一个示例,向您展示如何使用defaultValues
您可以在此处查看完整的解决方案:
以下是所有更改的文件:
App.js
... other code
// need to move state and function form Form to app
const [show_input, setshow_input] = useState(false);
const createInput = () => {
setshow_input(true);
};
const auto_text = () => {
setshow_input(false);
};
const forms = [
{
// validate based on show_input state
fields: show_input ? ["uname", "email", "password"] : ["uname", "email"], //to support multiple fields form
component: (register, errors, defaultValues) => (
<Form1
register={register}
errors={errors}
defaultValues={defaultValues}
auto_text={auto_text}
createInput={createInput}
show_input={show_input}
/>
)
},
{
fields: ["lname"],
component: (register, errors, defaultValues) => (
<Form2
register={register}
errors={errors}
defaultValues={defaultValues}
/>
)
},
{
component: (register, errors, defaultValues) => (
<Form3
register={register}
errors={errors}
defaultValues={defaultValues}
/>
)
}
];
... other code
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;
import React,{useState}来自“React”;
从“/components/Form1”导入Form1;
从“/components/Form2”导入Form2;
从“/components/Form3”导入Form3;
从“react hook form”导入{useForm};
函数main component(){
常数{
登记
触发验证,
默认值,
错误,
获取值
}=使用形式({
//您可以在此处设置默认值
默认值:{
uname:“Lol”
}
});
日志(“错误:”,错误);
const[currentForm,setCurrentForm]=useState(0);
//控制密码输入可见性和Form1字段
const[passwordVisible,setPasswordVisible]=useState(false);
常量showPassword=()=>{
setPasswordVisible(true);
};
常量hidePassword=()=>{
setPasswordVisible(false);
};
常数形式=[
{
字段:passwordVisible
?[“uname”、“email”、“password”]
:[“uname”,“email”],
组件:(寄存器,错误)=>(
)
},
{
字段:[“lname”],
组件:(寄存器,错误)=>(
)
},
{
组件:(寄存器,错误)=>(
)
}
];
常量moveToPrevious=()=>{
triggerValidation(表单[currentForm].fields)。然后(valid=>{
如果(有效)setCurrentForm(currentForm-1);
});
};
常量moveToNext=()=>{
triggerValidation(表单[currentForm].fields)。然后(valid=>{
如果(有效)setCurrentForm(currentForm+1);
});
};
const prevButton=currentForm!==0;
const nextButton=currentForm!==forms.length-1;
常量handleSubmit=e=>{
log(“整个表单数据-”,getValues());
};
返回(
{currentForm}
{forms.map(form=>form.component(寄存器,错误))}
{prevButton&&(
返回
)}
{nextButton&&(
下一个
)}
{currentForm===2&&(
提交
)}
);
}
出口d
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;