Reactjs 如何在material ui stepper中验证每个表单步骤?
典型材料界面步进器如下Reactjs 如何在material ui stepper中验证每个表单步骤?,reactjs,material-ui,react-final-form,Reactjs,Material Ui,React Final Form,典型材料界面步进器如下 export default function HorizontalLinearStepper() { const classes = useStyles(); const [activeStep, setActiveStep] = React.useState(0); const [skipped, setSkipped] = React.useState(new Set()); const steps = getSteps();
export default function HorizontalLinearStepper() {
const classes = useStyles();
const [activeStep, setActiveStep] = React.useState(0);
const [skipped, setSkipped] = React.useState(new Set());
const steps = getSteps();
const isStepOptional = step => {
return step === 1;
};
const isStepSkipped = step => {
return skipped.has(step);
};
const handleNext = () => {
let newSkipped = skipped;
if (isStepSkipped(activeStep)) {
newSkipped = new Set(newSkipped.values());
newSkipped.delete(activeStep);
}
setActiveStep(prevActiveStep => prevActiveStep + 1);
setSkipped(newSkipped);
};
const handleBack = () => {
setActiveStep(prevActiveStep => prevActiveStep - 1);
};
const handleSkip = () => {
if (!isStepOptional(activeStep)) {
// You probably want to guard against something like this,
// it should never occur unless someone's actively trying to break something.
throw new Error("You can't skip a step that isn't optional.");
}
setActiveStep(prevActiveStep => prevActiveStep + 1);
setSkipped(prevSkipped => {
const newSkipped = new Set(prevSkipped.values());
newSkipped.add(activeStep);
return newSkipped;
});
};
const handleReset = () => {
setActiveStep(0);
};
return (
<div className={classes.root}>
<Stepper activeStep={activeStep}>
{steps.map((label, index) => {
const stepProps = {};
const labelProps = {};
if (isStepOptional(index)) {
labelProps.optional = <Typography variant="caption">Optional</Typography>;
}
if (isStepSkipped(index)) {
stepProps.completed = false;
}
return (
<Step key={label} {...stepProps}>
<StepLabel {...labelProps}>{label}</StepLabel>
</Step>
);
})}
</Stepper>
<div>
{activeStep === steps.length ? (
<div>
<Typography className={classes.instructions}>
All steps completed - you're finished
</Typography>
<Button onClick={handleReset} className={classes.button}>
Reset
</Button>
</div>
) : (
<div>
<div className={classes.instructions}>{getStepContent(activeStep)}</div>
<div>
<Button disabled={activeStep === 0} onClick={handleBack} className={classes.button}>
Back
</Button>
{isStepOptional(activeStep) && (
<Button
variant="contained"
color="primary"
onClick={handleSkip}
className={classes.button}
>
Skip
</Button>
)}
<Button
variant="contained"
color="primary"
onClick={handleNext}
type="submit"
className={classes.button}
>
{activeStep === steps.length - 1 ? 'Finish' : 'Next'}
</Button>
</div>
</div>
)}
</div>
</div>
);
}
导出默认函数HorizontalLinearStepper(){
const classes=useStyles();
const[activeStep,setActiveStep]=React.useState(0);
const[skipped,setSkipped]=React.useState(new Set());
const steps=getSteps();
常量isStepOptional=步骤=>{
返回步骤===1;
};
常量isStepSkipped=步骤=>{
返回跳过。has(步骤);
};
常量handleNext=()=>{
让新闻剪辑=跳过;
如果(isStepSkipped(activeStep)){
newskiped=新集合(newskiped.values());
newskiped.delete(activeStep);
}
setActiveStep(prevActiveStep=>prevActiveStep+1);
设置剪辑(新闻剪辑);
};
常量把手=()=>{
setActiveStep(prevActiveStep=>prevActiveStep-1);
};
常量handleSkip=()=>{
如果(!IsStep可选(activeStep)){
//你可能想防范这样的事情,
//除非有人正积极地试图打破某些东西,否则它永远不会发生。
抛出新错误(“不能跳过非可选步骤”);
}
setActiveStep(prevActiveStep=>prevActiveStep+1);
设置跳过(已跳过=>{
const newskiped=新集合(prevSkipped.values());
添加(activeStep);
返回新闻稿;
});
};
常量handleReset=()=>{
setActiveStep(0);
};
返回(
{steps.map((标签,索引)=>{
const stepProps={};
常量labelProps={};
if(可选(索引)){
labelProps.optional=可选;
}
如果(已跳过(索引)){
stepProps.completed=false;
}
返回(
{label}
);
})}
{activeStep===steps.length(
所有步骤已完成-您已完成
重置
) : (
{getStepContent(activeStep)}
返回
{isstep可选(activeStep)&&(
跳过
)}
{activeStep===steps.length-1?'Finish':'Next'}
)}
);
}
下面是我为选择步骤创建的函数
function getStepContent(step) {
switch (step) {
case 0:
return <Step1/>;
case 1:
return <Step2/>;
case 2:
return 'This is the bit I really care about!';
default:
return 'Unknown step';
}
}
函数getStepContent(步骤){
开关(步骤){
案例0:
返回;
案例1:
返回;
案例2:
return‘这是我真正关心的一点!’;
违约:
返回“未知步骤”;
}
}
Step1和Step2是在构建内部具有2个表单和react final表单的组件
import React, { Component } from 'react';
import { Form } from 'react-final-form';
import initialValuesCreator from './creationMethods/initialValuesCreator';
import { validationCreator } from './creationMethods/validationSchemaCreator';
class CustomValidationForm extends Component {
render() {
const {
config ,children, submit = () => {}
} = this.props;
return (
<Form
onSubmit={(event) => {
submit(event);
}}
initialValues={initialValuesCreator(config)}
validate={values => validationCreator(values, config)}
render={({handleSubmit}) => (
<form noValidate autoComplete={'off'} onSubmit={handleSubmit}>
{children}
</form>
)}
/>
)
}
}
import React,{Component}来自'React';
从“react final Form”导入{Form};
从“/creationMethods/initialValuesCreator”导入initialValuesCreator;
从“./creationMethods/validationSchemaCreator”导入{validationCreator};
类CustomValidationForm扩展组件{
render(){
常数{
配置,子项,提交=()=>{}
}=这是道具;
返回(
{
提交(活动);
}}
initialValues={initialValuesCreator(配置)}
validate={values=>validationCreator(值,配置)}
render={({handleSubmit})=>(
{儿童}
)}
/>
)
}
}
问题来了。物料界面步进器具有handleNext功能。这是我的每一步提交。每一步都是带有验证的某种形式。当用户在第1步,他按下提交,我想向他显示输入错误(需要一些东西等),并防止跳转到下一步。Step1可以有多个小表单,因此当按下handleNext时,所有表单都应该进行验证。我想出的进行分步验证的最佳方法是将表单拆分为多个小表单,并让一个控制器组件将所有表单值组合在一起,就像中一样。我也在处理它 我最终做了什么来解决它:
export default function HorizontalLinearStepper() {
const classes = useStyles();
const [activeStep, setActiveStep] = React.useState(0);
const [skipped, setSkipped] = React.useState(new Set());
const steps = getSteps();
const myForm = React.useRef(null);
const isStepOptional = step => {
return step === 1;
};
const isStepSkipped = step => {
return skipped.has(step);
};
const handleNext = () => {
if (!myForm.current.checkValidity()) {
return;
}
let newSkipped = skipped;
if (isStepSkipped(activeStep)) {
newSkipped = new Set(newSkipped.values());
newSkipped.delete(activeStep);
}
setActiveStep(prevActiveStep => prevActiveStep + 1);
setSkipped(newSkipped);
};
const handleBack = () => {
setActiveStep(prevActiveStep => prevActiveStep - 1);
};
const handleSkip = () => {
if (!isStepOptional(activeStep)) {
// You probably want to guard against something like this,
// it should never occur unless someone's actively trying to break something.
throw new Error("You can't skip a step that isn't optional.");
}
setActiveStep(prevActiveStep => prevActiveStep + 1);
setSkipped(prevSkipped => {
const newSkipped = new Set(prevSkipped.values());
newSkipped.add(activeStep);
return newSkipped;
});
};
const handleReset = () => {
setActiveStep(0);
};
return (
<div className={classes.root}>
<Stepper activeStep={activeStep}>
{steps.map((label, index) => {
const stepProps = {};
const labelProps = {};
if (isStepOptional(index)) {
labelProps.optional = <Typography variant="caption">Optional</Typography>;
}
if (isStepSkipped(index)) {
stepProps.completed = false;
}
return (
<Step key={label} {...stepProps}>
<StepLabel {...labelProps}>{label}</StepLabel>
</Step>
);
})}
</Stepper>
<form action="/" method="POST" ref={myForm}>
{activeStep === steps.length ? (
<div>
<Typography className={classes.instructions}>
All steps completed - you're finished
</Typography>
<Button onClick={handleReset} className={classes.button}>
Reset
</Button>
</div>
) : (
<div>
<div className={classes.instructions}>{getStepContent(activeStep)}</div>
<div>
<Button disabled={activeStep === 0} onClick={handleBack} className={classes.button}>
Back
</Button>
{isStepOptional(activeStep) && (
<Button
variant="contained"
color="primary"
onClick={handleSkip}
className={classes.button}
>
Skip
</Button>
)}
<Button
variant="contained"
color="primary"
onClick={handleNext}
type="submit"
className={classes.button}
>
{activeStep === steps.length - 1 ? 'Finish' : 'Next'}
</Button>
</div>
</form>
)}
</div>
</div>
);
}
导出默认函数HorizontalLinearStepper(){
const classes=useStyles();
const[activeStep,setActiveStep]=React.useState(0);
const[skipped,setSkipped]=React.useState(new Set());
const steps=getSteps();
const myForm=React.useRef(null);
常量isStepOptional=步骤=>{
返回步骤===1;
};
常量isStepSkipped=步骤=>{
返回跳过。has(步骤);
};
常量handleNext=()=>{
如果(!myForm.current.checkValidity()){
返回;
}
让新闻剪辑=跳过;
如果(isStepSkipped(activeStep)){
newskiped=新集合(newskiped.values());
newskiped.delete(activeStep);
}
setActiveStep(prevActiveStep=>prevActiveStep+1);
设置剪辑(新闻剪辑);
};
常量把手=()=>{
setActiveStep(prevActiveStep=>prevA