如何使用Formik和MUI将值从外部API设置为输入字段?

发布于 2025-02-10 17:50:04 字数 2853 浏览 1 评论 0原文

我正在尝试将API的值输入使用Formik的TextField MUI组件。这个想法是表单是一个组件,我将其用于另一个组件,如果一个值来自API,则将其作为prop将其传递给表单组件,如果未传递,则Textfield组件为渲染以手动输入值。

这是表单组件的代码段使用setFieldValue接收到formik输入中的值。我还启用了enableReInitialize prop of formik。所有这些都是为了使iSvalid Formik prop识别值有效并启用提交按钮。

// FormComponent

onst valSchema = Yup.object().shape({
  batchNo: Yup.string()
    .required('Required'),
  item: Yup.string().required('Required'),
  price: Yup.string().required('Required'),
});

const ItemForm = (props) => {
return (
    <Grid container>
      <Grid item xs={12}>
        <Container maxWidth="md">
          <div>
            <Formik
              enableReinitialize
              initialValues={initialValues}
              validationSchema={valSchema}
              onSubmit={(values) => {
                localHandleSubmit(values);
              }}
            >
              {({ dirty, isValid, errors, handleChange, setFieldValue }) => (
                <Form>
                  <Grid container spacing={2}>
                    {props.batchValue ? (
                      <Grid item xs={12}>
                        <TextField name="batchNo" label="Batch No" value={props.batchValue} onChange={(e) => {
                            handleChange(e);
                            setFieldValue('batchNo', props.batchValue);}} />
                      </Grid>
                    ) : (
                      <Grid item xs={12}>
                        <TextField name="batchNo" label="Batch No" />
                      </Grid>
                    )}
                    <Grid item xs={6}>
                      <TextField name="item" label="Item" />
                    </Grid>
                    <Grid item xs={6}>
                      <TextField name="price" label="Price" />
                    </Grid>
                    <Grid item xs={12}>
                      <Button
                        fullWidth
                        variant="contained"
                        disabled={!isValid || !dirty}
                        type="submit"
                      >
                        {' '}
                        ADD
                      </Button>
                    </Grid>
                  </Grid>
                </Form>
              )}
            </Formik>
          </div>
        </Container>
      </Grid>
    </Grid>
  );
};

这就是我将值传递给表单组件的方式。

<DialogContent dividers>
       <FormComponent batchValue={batch} />
</DialogContent>

我遇到的问题是不能启用提交按钮,因此我发现Isvalid formik prop是错误的,并且需要此值的错误,因此Formik不识别从API传递的值是有效的。

我想知道如何完成这项工作。

I'm trying to enter a value from an API into a TextField MUI component that uses formik. The idea is that the form is one component and I'm using it into another component in which if a value comes from an API, then it is passed as prop to the form component, if it is not passed, then the TextField component is rendered in order to enter the value manually.

This is the code snippet from the form component, in which if I have a prop passed the value is set to value and the onChange prop of the TextField is managed to set update the value received into the formik input using setFieldValue. I have also enabled the enableReinitialize prop on formik. All of this in order to make the isValid formik prop recognize the value as valid and enable the submit button.

// FormComponent

onst valSchema = Yup.object().shape({
  batchNo: Yup.string()
    .required('Required'),
  item: Yup.string().required('Required'),
  price: Yup.string().required('Required'),
});

const ItemForm = (props) => {
return (
    <Grid container>
      <Grid item xs={12}>
        <Container maxWidth="md">
          <div>
            <Formik
              enableReinitialize
              initialValues={initialValues}
              validationSchema={valSchema}
              onSubmit={(values) => {
                localHandleSubmit(values);
              }}
            >
              {({ dirty, isValid, errors, handleChange, setFieldValue }) => (
                <Form>
                  <Grid container spacing={2}>
                    {props.batchValue ? (
                      <Grid item xs={12}>
                        <TextField name="batchNo" label="Batch No" value={props.batchValue} onChange={(e) => {
                            handleChange(e);
                            setFieldValue('batchNo', props.batchValue);}} />
                      </Grid>
                    ) : (
                      <Grid item xs={12}>
                        <TextField name="batchNo" label="Batch No" />
                      </Grid>
                    )}
                    <Grid item xs={6}>
                      <TextField name="item" label="Item" />
                    </Grid>
                    <Grid item xs={6}>
                      <TextField name="price" label="Price" />
                    </Grid>
                    <Grid item xs={12}>
                      <Button
                        fullWidth
                        variant="contained"
                        disabled={!isValid || !dirty}
                        type="submit"
                      >
                        {' '}
                        ADD
                      </Button>
                    </Grid>
                  </Grid>
                </Form>
              )}
            </Formik>
          </div>
        </Container>
      </Grid>
    </Grid>
  );
};

This is how I'm passing the value to the form component.

<DialogContent dividers>
       <FormComponent batchValue={batch} />
</DialogContent>

The problem I'm having is that the submit button is not enable, thus I found out that the isValid formik prop is false and the error for this value is required, so formik is not recognizing the value passed from the API as valid.

I would like to know how I can make this work.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

霊感 2025-02-17 17:50:04

我知道这个问题很久以前就问了,但这可能对某人有帮助。诀窍是使用initialValues对象设置输入值,并使用一个空字符串来退缩到普通的可编辑输入。

// Suppose data is the prop returned from an API response
const data = {
  batchNo: "04930",
  item: "Gizmo",
  price: "24.43",
};

<Formik
    enableReinitialize
    initialValues={{
      batchNo: data?.batchNo ?? "",
      item: data?.item ?? "",
      price: data?.price ?? ""
    }}
    validationSchema={valSchema}
    onSubmit={(values) => {
      localHandleSubmit(values);
    }}
  />

现在,输入字段的默认值将是来自API Prop的值。通过利用??无效的合并操作员,当响应不确定时,我们会退缩为空的可编辑输入。

为了将值输入输入,而不是直接传递道具数据,您可以使用持有每个输入数据的formik value对象。

{({ dirty, isValid, errors, handleChange, values }) => (
    <Form>
      <Grid container spacing={2}>
        {values.batchNo ? (
          <Grid item xs={12}>
            <TextField
              name="batchNo"
              label="Batch No"
              value={values.batchNo}
              onChange={handleChange}
            />
          </Grid>
        ) : (
          <Grid item xs={12}>
            <TextField
              name="batchNo"
              label="Batch No"
              value={values.batchNo}
              onChange={handleChange}
            />
          </Grid>
        )}
        <Grid item xs={6}>
          <TextField
            name="item"
            label="Item"
            value={values.item}
            onChange={handleChange}
          />
        </Grid>
        <Grid item xs={6}>
          <TextField
            name="price"
            label="Price"
            value={values.price}
            onChange={handleChange}
          />
        </Grid>
        <Grid item xs={12}>
          <Button
            fullWidth
            variant="contained"
            disabled={!isValid || !dirty}
            type="submit"
          >
            {" "}
            ADD
          </Button>
        </Grid>
      </Grid>
    </Form>
  )}

I know this question was asked a long time ago, but this might be helpful to someone. The trick is to set the input values using the initialValues object and use an empty string to fallback to plain editable inputs.

// Suppose data is the prop returned from an API response
const data = {
  batchNo: "04930",
  item: "Gizmo",
  price: "24.43",
};

<Formik
    enableReinitialize
    initialValues={{
      batchNo: data?.batchNo ?? "",
      item: data?.item ?? "",
      price: data?.price ?? ""
    }}
    validationSchema={valSchema}
    onSubmit={(values) => {
      localHandleSubmit(values);
    }}
  />

Now the default values of the input fields will be the values coming from the API prop. By utilizing the ?? nullish coalescing operator, we fallback to empty editable inputs when the response is undefined.

To get the values into the input, instead of passing the prop data directly, you can utilize the formik values object which holds the data of each inputs.

{({ dirty, isValid, errors, handleChange, values }) => (
    <Form>
      <Grid container spacing={2}>
        {values.batchNo ? (
          <Grid item xs={12}>
            <TextField
              name="batchNo"
              label="Batch No"
              value={values.batchNo}
              onChange={handleChange}
            />
          </Grid>
        ) : (
          <Grid item xs={12}>
            <TextField
              name="batchNo"
              label="Batch No"
              value={values.batchNo}
              onChange={handleChange}
            />
          </Grid>
        )}
        <Grid item xs={6}>
          <TextField
            name="item"
            label="Item"
            value={values.item}
            onChange={handleChange}
          />
        </Grid>
        <Grid item xs={6}>
          <TextField
            name="price"
            label="Price"
            value={values.price}
            onChange={handleChange}
          />
        </Grid>
        <Grid item xs={12}>
          <Button
            fullWidth
            variant="contained"
            disabled={!isValid || !dirty}
            type="submit"
          >
            {" "}
            ADD
          </Button>
        </Grid>
      </Grid>
    </Form>
  )}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文