wan*_*mer 5 reactjs material-ui react-final-form
下面是典型的 material-ui 步进器。
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>
);
}
Run Code Online (Sandbox Code Playgroud)
这是我为选择步骤创建的功能
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';
}
}
Run Code Online (Sandbox Code Playgroud)
Step1 和 Step2 是在 build 内部有 2 个表单的组件,带有 react-final-form
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>
)}
/>
)
}
}
Run Code Online (Sandbox Code Playgroud)
问题来了。Material ui stepper 有 handleNext 功能。它是我为每一步提交的。每一步都是某种形式的验证。当用户在 step1 并且他按下提交时,我想向他展示输入错误(需要一些东西等)并防止跳转到下一步。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>
);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4482 次 |
| 最近记录: |