Formik + Material UI 当我提交表单并尝试更改值时出现错误

Formik + Material UI bug when i submit form and try to change the values

我有这个 formik 代码,我有一个 handleSubmit 可以获取值并更改其他数据的值:

async function handleSubmit(values) {
  const newValues = {...values};
  newValues.employee_type = newValues.employee_type.id
  newValues.specialties.main = newValues.specialties.main.id
  newValues.specialties.secondary = newValues.specialties.secondary.id
  newValues.specialties.tertiary = newValues.specialties.tertiary.id

  console.log(newValues)
}

当我尝试更改来自 formik 的值时,屏幕中的输入值也会发生变化。例如这一行: newValues.employee_type = newValues.employee_type.id默认情况下 employee_type 就像一个带有 id 键的对象一样来到我身边,我想用它本身内部的 id 替换这个对象。但是当我这样做时,名称为 employee_type 的输入在屏幕上变成空的,有人可以帮助我吗?

          initialValues={{ ...initialValues }}
          validationSchema={validator}
          onSubmit={handleSubmit}
          enableReinitialize
        >
          {({ handleBlur, setFieldValue, getFieldProps, resetForm }) => (
            <Form>
              <Box sx={{ width: "100%" }}>
                <Grid container spacing={2} sx={{}}>
                  <Grid item xs={4}>
                    <FormTextField name="name" label="Nome" />
                  </Grid>
                  <Grid item xs={3}>
                    <FormDate
                      name="birthday"
                      label="Data de Nascimento"
                      required={true}
                    />
                  </Grid>
                  <Grid item xs={3} alignItems="stretch">
                    <FormSelectField
                      name="genre"
                      label="Gênero"
                      options={genders}
                      required
                    />
                  </Grid>
                  <Grid item xs={2} alignItems="stretch">
                    <FormSelectField
                      name="nationality"
                      label="Nacionalidade"
                      options={countries}
                      required
                    />
                  </Grid>
                  <Grid item xs={4} alignItems="stretch">
                    <FormTextField name="social_name" label="Nome Social" />
                  </Grid>
                  <Grid item xs={3} alignItems="stretch">
                    <FormTextField
                      name="naturality"
                      label="Naturalidade"
                      required
                    />
                  </Grid>
                  <Grid item xs={3} alignItems="stretch">
                    <FormSelectField
                      name="ethnicity"
                      label="Etnia"
                      options={ethnicity}
                      required
                    />
                  </Grid>
                  <Grid item xs={2} alignItems="stretch">
                    <FormSelectField
                      name="marital_status"
                      label="Estado Civil"
                      options={states}
                    />
                  </Grid>
                  <Grid item xs={4} alignItems="stretch">
                    <FormTextField
                      name="physic_national"
                      label="CPF"
                      mask="999.999.999-99"
                      required
                    />
                  </Grid>
                  <Grid item xs={4} alignItems="stretch">
                    <FormTextField
                      name="ident_national"
                      label="Registro Geral"
                      required
                    />
                  </Grid>
                  <Grid item xs={4} alignItems="stretch">
                    <FormTextField
                      name="issuing_body"
                      label="Orgão Emissor"
                      required
                    />
                  </Grid>
                </Grid>
                <div
                  style={{
                    marginBottom: "20px",
                    marginTop: "20px",
                  }}
                >
                  <Typography
                    variant="h7"
                    color="secondary"
                    fontWeight="500"
                    sx={{ marginTop: "20px" }}
                  >
                    Dados de Contato
                  </Typography>
                </div>
                <Grid container spacing={2} sx={{}}>
                  <Grid item xs={4} alignItems="stretch">
                    <FormTextField
                      name="contact.email"
                      type="email"
                      label="Email"
                      required
                    />
                  </Grid>
                  <Grid item xs={4} alignItems="stretch">
                    <FormTextField
                      name="contact.phone"
                      label="Telefone"
                      mask="+99 (99) 99999-9999"
                    />
                  </Grid>
                  <Grid item xs={4} alignItems="stretch">
                    <FormTextField name="contact.cell_phone" label="Celular" />
                  </Grid>
                  <br></br>
                  <Grid item xs={2}>
                    <FormTextField
                      name="contact.cep"
                      label="CEP"
                      required
                      onBlur={(e) => handleOnBlur(e, handleBlur, setFieldValue)}
                      mask="99999-999"
                    />
                  </Grid>
                  <Grid item xs={2}>
                    <FormTextField
                      name="contact.address_number"
                      label="Número"
                      required
                      type="number"
                      InputProps={{ inputProps: { min: 0 } }}
                    />
                  </Grid>
                  <Grid item xs={2}>
                    <FormTextField
                      name="contact.street"
                      fullWidth
                      size="small"
                      label="Logradouro"
                      disabled={true}
                      InputLabelProps={{ shrink: true }}
                    />
                  </Grid>
                  <Grid item xs={2}>
                    <FormTextField
                      name="contact.district"
                      fullWidth
                      size="small"
                      label="Bairro"
                      disabled={true}
                      InputLabelProps={{ shrink: true }}
                    />
                  </Grid>
                  <Grid item xs={2}>
                    <FormTextField
                      name="contact.county"
                      fullWidth
                      size="small"
                      label="Localidade"
                      disabled={true}
                      InputLabelProps={{ shrink: true }}
                    />
                  </Grid>
                  <Grid item xs={2}>
                    <FormTextField
                      name="contact.state"
                      fullWidth
                      size="small"
                      label="Estado"
                      disabled={true}
                      InputLabelProps={{ shrink: true }}
                    />
                  </Grid>
                </Grid>
                <div
                  style={{
                    marginBottom: "20px",
                    display: "flex",
                  }}
                >
                  <Typography
                    variant="h7"
                    color="secondary"
                    fontWeight="500"
                    sx={{ marginTop: "20px" }}
                  >
                    Dados de Acesso
                  </Typography>
                </div>
                <Grid container spacing={2} sx={{}}>
                  <Grid item xs={4}>
                    <FormTextField
                      name="user_login"
                      label="Nome de Acesso"
                      autoComplete="username"
                    />
                  </Grid>
                  <Grid item xs={4}>
                    <FormTextField
                      name="pass_login"
                      label="Senha"
                      type="password"
                      autoComplete="new-password"
                    />
                  </Grid>
                  <Grid item xs={4}>
                    <FormTextField
                      name="pass_login_confirmation"
                      label="Repita a Senha"
                      type="password"
                      autoComplete="new-password"
                    />
                  </Grid>
                  <Grid item xs={4}>
                    {/* <FormTextField name="" label="Confirmar Senha" /> */}
                  </Grid>
                </Grid>
                <div
                  style={{
                    marginBottom: "20px",
                    display: "flex",
                  }}
                >
                  <Typography variant="h7" color="secondary" fontWeight="500">
                    Dados Profissionais
                  </Typography>
                </div>
                <Grid container spacing={2}>
                  <Grid item xs={6}>
                    <Grid container spacing={2}>
                      <Grid item xs={12}>
                        <FormSearchSelectField
                          name="employee_type"
                          options={types}
                          label="Tipo do Prestador :"
                          getOptionLabel={(type) =>
                            type.description ? type.description : ""
                          }
                          handleChange={(_, value) => {
                            setFieldValue(
                              "council",
                              value && value.council ? value.council.id : ""
                            );
                            setCouncil(
                              (value && value.council.description) || ""
                            );
                            setFieldValue("employee_type", value);
                          }}
                          isOptionEqualToValue={(type, value) =>
                            type.id === value.id ? true : false
                          }
                        />
                      </Grid>
                      <Grid item xs={12}>
                        <TextField
                          fullWidth
                          size="small"
                          InputLabelProps={{
                            shrink: true,
                          }}
                          name=""
                          label="Conselho :"
                          multiple
                          InputProps={{
                            value: council,
                          }}
                          disabled
                        ></TextField>
                      </Grid>
                      <Grid item xs={6}>
                        <FormTextField
                          name="council_uf"
                          label="UF :"
                          select
                          multiple
                        >
                          {ufs.map((item, key) => {
                            return (
                              <MenuItem key={item} value={item}>
                                {item}
                              </MenuItem>
                            );
                          })}
                        </FormTextField>
                      </Grid>
                      <Grid item xs={6}>
                        <FormTextField
                          name="council_ident"
                          label="Número :"
                          type="number"
                          InputProps={{ inputProps: { min: 0 } }}
                        ></FormTextField>
                      </Grid>
                    </Grid>
                  </Grid>
                  <Grid item xs={6}>
                    <Box
                      sx={{
                        borderRadius: 1,
                        display: "flex",
                        alignItems: "center",
                        justifyContent: "center",
                      }}
                    >
                      <Grid container spacing={2}>
                        <Grid item xs={12}>
                          <FormSearchSelectField
                            name="specialties.main"
                            options={specialties.filter((item) => {
                              let secondary =
                                getFieldProps("specialties").value.secondary;
                              let tertiary =
                                getFieldProps("specialties").value.tertiary;
                              if (secondary && tertiary) {
                                if (
                                  item.id !== secondary.id &&
                                  item.id !== tertiary.id
                                ) {
                                  return item;
                                }
                              } else if (secondary) {
                                if (item.id !== secondary.id) {
                                  return item;
                                }
                              } else if (tertiary) {
                                if (item.id !== tertiary.id) {
                                  return item;
                                }
                              } else {
                                return item;
                              }
                            })}
                            label="Especialidade Principal :"
                            required
                            getOptionLabel={(specialty) =>
                              specialty.describe ? specialty.describe : ""
                            }
                            handleChange={(_, value) => {
                              setDisableOther(false);
                              setFieldValue("specialties.main", value);
                            }}
                            isOptionEqualToValue={(specialty, value) => {
                              return specialty.id === value.id ? true : false;
                            }}
                          />
                        </Grid>
                        <Grid item xs={12}>
                          <FormSearchSelectField
                            name="specialties.secondary"
                            options={specialties.filter((item) => {
                              let main = getFieldProps("specialties").value.main;
                              let tertiary = getFieldProps("specialties").value.tertiary;
                              if (main && tertiary) {
                                if (
                                  item.id !== main.id &&
                                  item.id !== tertiary.id
                                ) {
                                  return item;
                                }
                              } else if (main) {
                                if (item.id !== main.id) {
                                  return item;
                                }
                              } else if (tertiary) {
                                if (item.id !== tertiary.id) {
                                  return item;
                                }
                              } else {
                                return item;
                              }
                            })}
                            label="Outras :"
                            getOptionLabel={(specialty) =>
                              specialty.describe ? specialty.describe : ""
                            }
                            list={[]}
                            handleChange={(_, value) => {
                              setDisableOther(false);
                              setFieldValue("specialties.secondary", value);
                            }}
                            isOptionEqualToValue={(specialty, value) => {
                              return specialty.id === value.id ? true : false;
                            }}
                          />
                        </Grid>
                        <Grid item xs={12}>
                          <FormSearchSelectField
                            name="specialties.tertiary"
                            options={specialties.filter((item) => {
                              let main = getFieldProps("specialties").value.main;
                              let secondary = getFieldProps("specialties").value.secondary;
                              if (main && secondary) {
                                if (
                                  item.id !== main.id &&
                                  item.id !== secondary.id
                                ) {
                                  return item;
                                }
                              } else if (main) {
                                if (item.id !== main.id) {
                                  return item;
                                }
                              } else if (secondary) {
                                if (item.id !== secondary.id) {
                                  return item;
                                }
                              } else {
                                return item;
                              }
                            })}
                            label="Outras :"
                            getOptionLabel={(specialty) =>
                              specialty.describe ? specialty.describe : ""
                            }
                            list={[]}
                            handleChange={(_, value) => {
                              setDisableOther(false);
                              setFieldValue("specialties.tertiary", value);
                            }}
                            isOptionEqualToValue={(specialty, value) => {
                              return specialty.id === value.id ? true : false;
                            }}
                          />
                        </Grid>
                      </Grid>
                    </Box>
                  </Grid>
                  <Grid item>
                    {loading ? (
                      <Button
                        disabled
                        sx={{
                          bgcolor: "rgba(8, 153, 186, 0.1)",
                          color: "white",
                        }}
                      >
                        <CircularProgress
                          color="primary"
                          size={20}
                          sx={{ mr: 1 }}
                        />{" "}
                        Cadastrando...
                      </Button>
                    ) : (
                      <SubmitButton>Cadastrar</SubmitButton>
                    )}
                  </Grid>
                </Grid>
              </Box>
            </Form>
          )}
        </Formik>

const newValues = {...values} - 创建一个新对象 'newValues' 但所有键都引用与 'values' 中的键相同的对象。您需要对 'values' 进行深度克隆。 为此,请使用 lodash:

const newValues = _.cloneDeep(values)

或更脏的方法(一般不推荐):

const newValues = JSON.parse(JSON.stringify(values));