3

我正在制作“主要照顾者”信息表,并且有一个按钮可以动态添加“紧急联系人”。

使用<FieldArray name="emergencyContacts" />, 有没有办法自动name<Field />组件添加父组件name和子组件的前缀index,以便 Formik 知道在哪里更新它values


这是我的简化代码:

const DEFAULT_CAREGIVER = {
  firstName: '',
  lastName: '',
};

function ContactInfoForm({ parentName }) {

  // I have to prefix the names so that Formik updates the correct values
  // I'd like to remove this prefix logic, and hopefully use existing properties:
  // "This component is rendered within a <FieldArray name="emergencyContacts" />"
  function prefix(name) {
    return parentName ? `${parentName}.${name}` : name;
  }

  return (
    <React.Fragment>
      <Field
        component={TextField}
        id="firstName"
        label="First Name"
        name={prefix('firstName')}
        required
      />
      <Field
        component={TextField}
        id="lastName"
        label="Last Name"
        name={prefix('lastName')}
        required
      />
    </React.Fragment>
  );
}

function CaregiverForm({ name }) {
  return (
    // I'm hoping to not have to pass the prefix path along
    // We have lots of reusable components in this form
    <ContactInfoForm parentName={name} />
  );
}

class PrimaryCaregiverForm extends React.Component {
  renderEmergencyContacts = fieldArray => {
    const { values } = this.props;

    return (
      <React.Fragment>
        {values.emergencyContacts.length > 0 &&
          values.emergencyContacts.map((contact, index) => (
            <div key={index}>
              <PageTitle>Emergency Contact {index + 1}</PageTitle>
              <CloseButton onClick={() => fieldArray.remove(index)} />
              <CaregiverForm
                name={`${fieldArray.name}.${index}`}
                {...this.props}
              />
            </div>
          ))}
        <AddEmergencyContactButton
          onClick={() => fieldArray.push(DEFAULT_CAREGIVER)}
        />
      </React.Fragment>
    );
  };

  render() {
    const { handleSubmit } = this.props;
    return (
      <Form onSubmit={handleSubmit}>
        <PageTitle>Primary Caregiver</PageTitle>
        <CaregiverForm {...this.props} />
        <FieldArray
          name="emergencyContacts"
          render={this.renderEmergencyContacts}
        />
        <Button type="submit">Save & Continue</Button>
      </Form>
    );
  }
}

const caregiverValidationSchema = {
  firstName: Yup.string().required('First name is required.'),
  lastName: Yup.string().required('Last name is required.'),
};

const PrimaryCaregiverPage = withFormik({
  mapPropsToValues: () => ({
    ...DEFAULT_CAREGIVER,
    emergencyContacts: [],
  }),
  validationSchema: Yup.object().shape({
    ...caregiverValidationSchema,
    emergencyContacts: Yup.array().of(
      Yup.object().shape(caregiverValidationSchema),
    ),
  }),
})(PrimaryCaregiverForm);
4

0 回答 0