Поместите имя компонента узла в круглые скобки после определения другого компонента - PullRequest
0 голосов
/ 13 сентября 2018

Я пытаюсь использовать formik в реакции. Я нашел код, подобный этому:

import React from 'react';
import * as Yup from 'yup';
import { withFormik, FormikProps, FormikErrors, Form, Field } from 'formik';

// Shape of form values
interface FormValues {
  email: string;
  password: string;
}

interface OtherProps {
  message: string;
}

// Aside: You may see InjectedFormikProps<OtherProps, FormValues> instead of what comes below in older code.. InjectedFormikProps was artifact of when Formik only exported a HoC. It is also less flexible as it MUST wrap all props (it passes them through).
const InnerForm = (props: OtherProps & FormikProps<FormValues>) => {
  const { touched, errors, isSubmitting, message } = props;
  return (
    <Form>
      <h1>{message}</h1>
      <Field type="email" name="email" />
      {touched.email && errors.email && <div>{errors.email}</div>}

      <Field type="password" name="password" />
      {touched.password && errors.password && <div>{errors.password}</div>}

      <button type="submit" disabled={isSubmitting}>
        Submit
      </button>
    </Form>
  );
};

// The type of props MyForm receives
interface MyFormProps {
  initialEmail?: string;
  message: string; // if this passed all the way through you might do this or make a union type
}

function isValidEmail(email: string): boolean {
  const at = email.indexOf('@');
  const lastDot = email.lastIndexOf('.');
  const valid = at > 0 && lastDot > at + 1 && lastDot < email.length - 1;
  return valid;
}

// Wrap our form with the using withFormik HoC
const MyForm = withFormik<MyFormProps, FormValues>({
  // Transform outer props into form values
  mapPropsToValues: props => {
    return {
      email: props.initialEmail || '',
      password: '',
    };
  },

  // Add a custom validation function (this can be async too!)
  validate: (values: FormValues) => {
    let errors: FormikErrors<any> = {};
    if (!values.email) {
      errors.email = 'Required';
    } else if (!isValidEmail(values.email)) {
      errors.email = 'Invalid email address';
    }
    return errors;
  },

  handleSubmit: values => {
    // do submitting things
  },
})(InnerForm);

// Use <MyForm /> wherevs
export default class Commission extends React.PureComponent<undefined> {
  public render() {
    return (
      <div>
        <h1>My App</h1>
        <p>This can be anywhere in your application</p>
        <MyForm message="Sign up" />
      </div>
    );
  }
}

Я заметил, что он поставил InnerForm после определения MyForm. А в определении InnerForm у реквизита есть такие элементы, как touched, errors, isSubmitting, message, которые нигде не определены. Я хочу спросить, как соотносятся эти два компонента и как между ними проходит реквизит.

1 Ответ

0 голосов
/ 13 сентября 2018

withFormik представляется компонентом высшего порядка: https://reactjs.org/docs/higher-order-components.html

Это функция, которая по существу берет существующий компонент (в данном случае InnerForm) и, при необходимости, конфигурацию (объект сmapPropsToValues и handleSubmit) и создает новый компонент (MyForm).

Они обычно используются для добавления общих функциональных возможностей к существующим компонентам, которые могут включать предоставление значений по умолчанию для реквизита --- обычно HOCsтребовать, чтобы компоненты, которые они украшают, имели определенные реквизиты, которые они могли бы добавить

...