带有 React、Formik 和 Material UI 的多步骤表单,带有复选框和自动完成的问题

问题描述 投票:0回答:1

我希望你能在这部分帮助我,所以在获取数据输入和使用 yup 验证字段时,我对步进器没有问题,对表单也没有问题。

但我对复选框和自动完成有疑问。当我返回上一步时,我丢失了我已经输入的值并且验证不再适用于复选框和自动完成字段。

有一个我为复选框制作的钩子示例,稍后将在表单中使用:

const CheckBoxField = (props) => {
  const { label, ...rest } = props;
  const [field, meta, helper] = useField(props);
  const { setValue } = helper;
  const [touched, error] = at(meta, "touched", "error");
  const isError = error && touched && true;
  function __renderHelperText() {
    if (isError) {
      return <FormHelperText>{error}</FormHelperText>;
    }
  }
  function _onChange(event) {
    setValue(event.target.checked);
  }

  const configFormControl = {
    ...field,
    ...rest,
    onChange: _onChange,
  };
  return (
    <FormControl
      component="fieldset"
      {...configFormControl}
      error={Boolean(isError)}
    >
      <FormControlLabel
        // value={field.checked}
        checked={field.checked}
        label={label}
        onChange={_onChange}
        control={
          <BpCheckbox
            {...configFormControl}
            // checked={field.checked}
            color="primary"
          />
        }
        color="primary"
      />
      {__renderHelperText()}
    </FormControl>
  );
}; 

还有验证代码:

import * as yup from "yup";
 
import signUpFormModel from "../signUpFormModel";

const {
  formField: {
    terms //Boolean , used in checkboxes, should be true
  },
} = signUpFormModel;

const signUpValidationSchema = [
  yup.object().shape({
    [terms.name]: yup.boolean().oneOf([true], `${terms.requiredErrMsg}`), 
    //other fields ...
  }),
  //other forms ...
 
];

export default signUpValidationSchema;

我的初始值:

import signUpFormModel from "../signUpFormModel";

const {
  formField: {
    terms,
  },
} = signUpFormModel;

const formInitialValue = {
  [terms.name]: false,
};

export default formInitialValue;

和一些道具助手(用作我表格的模型)

import React, { Fragment } from "react";
import { Link } from "@mui/material";

const signUpFormModel = {
  formId: "registration",
  formField: {
 
    terms: {
      type: "checkbox",
      name: "terms",
      id: "terms",
      label: () => (
        <Fragment>
          J'accepte les{" "}
          <Link href="#" variant="body2">
            termes et conditions générales d'utilisation
          </Link>{" "}
          et la{" "}
          <Link href="#" variant="body2">
            politique de confidentialité
          </Link>
          .
        </Fragment>
      ),
      requiredErrMsg: "Vous devez accepter les termes et conditions",
    },
    
    
  },
};

export default signUpFormModel;

最后是表格本身:

import React from "react";
import { Grid } from "@mui/material";
import CheckBoxField from "../CheckBoxField";
 
 
const PrimarySignUpForm = (props) => {
  const {
    formField: {
      terms,
    },
  } = props;
  return (
    <Grid container spacing={2}>
      <Grid item xs={12}>
        <CheckBoxField name={terms.name} label={terms.label()} />
      </Grid>
    </Grid>
  );
};

export default PrimarySignUpForm;

这就是我制作步进器的方式:

import React, { Fragment, useState } from "react";
import SignUpFormLogs from "../forms/SignUpFormLogs";
import { Formik, Form } from "formik";
import formInitialValuefrom from "../formModel/formInitialValue";
import signUpFormModel from "../formModel/signUpFormModel";
import signUpValidationSchema from "../formModel/signUpValidationSchema";
import {
  Button,
  Link,
  Step,
  StepLabel,
  Stepper,
  Typography,
} from "@mui/material";
import { Box } from "@mui/system";
 


const steps = ["step1"];
const { formId, formField } = signUpFormModel;

function _renderSteps(step) {
  switch (step) {
    case "step1":
      return <SignUpFormLogs formField={formField} />;
    default:
      return <div>Not Found</div>;
  }
}

function _sleep(ms) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

const SignUp = () => {
  const [activeStep, setActiveStep] = useState(0);
  const currentValidationSchema = signUpValidationSchema[activeStep]; //activeStep
  const isLastStep = activeStep === steps.length - 1;

  async function _submitForm(values, actions) {
    await _sleep(1000);
    console.log(JSON.stringify(values, null, 2));
    actions.setSubmitting(false);
    setActiveStep(activeStep + 1);
  }

  function _handleSubmit(values, actions) {
    if (isLastStep) {
      _submitForm(values, actions);
    } else {
      setActiveStep(activeStep + 1);
      actions.setTouched({});
      actions.setSubmitting(false);
    }
  }

  function _handleBack() {
    setActiveStep(activeStep - 1);
  }

  return (
    <Fragment>
      <Stepper activeStep={activeStep} sx={{ pt: 3, pb: 5 }}>
        {steps.map((label) => (
          <Step key={label}>
            <StepLabel>{label}</StepLabel>
          </Step>
        ))}
      </Stepper>

      {activeStep === steps.length ? (
        <Typography variant="h6">Last step</Typography>
      ) : (
        <Formik
          initialValues={formInitialValuefrom}
          validationSchema={currentValidationSchema}
          onSubmit={_handleSubmit}
        >
          {({ isSubmitting }) => (
            <Form id={formId}>
              {_renderSteps(steps[activeStep])}

              {activeStep !== 0 && (
                <Button
                  onClick={_handleBack}
                  disabled={isSubmitting}
                  variant="outlined"
                  color="primary"
                  sx={{ mt: 4, mb: 2 }}
                >
                  Back
                </Button>
              )}

              <Button
                type="submit"
                disabled={isSubmitting}
                variant="contained"
                color="primary"
                sx={{ mt: 4, mb: 2 }}
              >
                {isLastStep ? "Enregistrer" : "Suivant"}
              </Button>

              {isSubmitting && (
                <Typography variant="h6">submitting...</Typography>
              )}
            </Form>
          )}
        </Formik>
      )}
    </Fragment>
  );
};

export default SignUp;

reactjs forms material-ui formik yup
1个回答
0
投票

你得到答案了吗?我也面临同样的问题。如果您找到解决方案,请帮助我

© www.soinside.com 2019 - 2024. All rights reserved.