Formik и Material-UI - PullRequest
       15

Formik и Material-UI

0 голосов
/ 31 августа 2018

Я пытаюсь использовать Formik с текстовым полем Material-UI. Вот так:

import TextField from '@material-ui/core/TextField';
import {
  Field,
  FieldProps,
  Form,
  Formik,
  FormikErrors,
  FormikProps
} from 'formik';
import React, { Component } from 'react';

interface IMyFormValues {
  firstName: string;
}

class CreateAgreementForm extends Component<{}> {
  public render() {
    return (
      <div>
        <h1>My Example</h1>
        <Formik
          initialValues={{ firstName: '' }}
          // tslint:disable-next-line:jsx-no-lambda
          onSubmit={(values: IMyFormValues) => alert(JSON.stringify(values))}
          // tslint:disable-next-line:jsx-no-lambda
          validate={(values: IMyFormValues) => {
            const errors: FormikErrors<IMyFormValues> = {};
            if (!values.firstName) {
              errors.firstName = 'Required';
            }
            return errors;
          }}
          // tslint:disable-next-line:jsx-no-lambda
          render={(formikBag: FormikProps<IMyFormValues>) => (
            <Form>
              <Field
                name="firstName"
                render={({ field, form }: FieldProps<IMyFormValues>) => (
                  <TextField
                    error={Boolean(
                      form.errors.firstName && form.touched.firstName
                    )}
                    helperText={
                      form.errors.firstName &&
                      form.touched.firstName &&
                      String(form.errors.firstName)
                    }
                  />
                )}
              />
            </Form>
          )}
        />
      </div>
    );
  }
}

export default CreateAgreementForm;

Я хочу, чтобы Formik отвечал за валидацию и Material-UI за внешний вид. Я хочу передать error.firstName компоненту TextField, но ошибка отображается неправильно. Как я могу это исправить, чтобы было понятно? Я не хочу писать свой собственный компонент TextField. Или, может быть, есть другая популярная библиотека для форм?

Ответы [ 3 ]

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

Как упомянуто в комментариях, на самом деле может быть хорошей идеей реализовать компоненты "обертки", как они это делали в следующих примерах из Formik или ReactFinalForm:

Идея та же: реализовать пользовательские компоненты-оболочки, чтобы обернуть компоненты Material-UI и отобразить реквизиты API Formik или ReactFinalForm.

Преимущества этого подхода состоят в том, чтобы централизованно отображать в одном месте отображение между двумя платформами, чтобы вы не повторяли отображение каждый раз, и если одна из структур вносит критические изменения, вам просто нужно изменить эту пользовательскую "оболочку". "компоненты.

0 голосов
/ 12 декабря 2018

Вы можете попробовать это: https://github.com/daixianceng/formik-material-fields

Установка:

npm install --save formik-material-fields

Использование:

import React, { Component } from 'react';
import { Formik, Form } from 'formik';
import * as Yup from 'yup';
import { FormikTextField } from 'formik-material-fields';

const validationSchema = Yup.object().shape({
  username: Yup.string().required(),
});

const initialValues = {
  username: '',
};

class MyForm extends Component {
  render() {
    return (
      <Formik
        initialValues={initialValues}
        validationSchema={validationSchema}
        onSubmit={this.props.onSubmit}
      >
        {({ isValid }) => (
          <Form autoComplete="off">
            <FormikTextField
              name="username"
              label="Username"
              margin="normal"
              fullWidth
            />
          </Form>
        )}
      </Formik>
    );
  }
}
0 голосов
/ 02 сентября 2018

Я не думаю, что вам нужна другая библиотека или даже создается ваша собственная обертка, я думаю, что вам нужно немного подправить свой код.

Одна из проблем, с которой вы столкнулись, заключается в том, что вы не передаете функцию onChange в Material TextField, поэтому значение формы firstName всегда равно null, поэтому вы всегда получаете сообщение об ошибке, даже если вы ввели имя. Попробуйте добавить имя или идентификатор в свой TextField и функцию onChange, например:

<Field
    validateOnBlur
    validateOnChange
    name="firstName"
    render={({ field, form }) => (
    <TextField
        name={"firstName"}
        error={
            Boolean(form.errors.firstName && form.touched.firstName)
        }
        onChange={formikBag.handleChange}
        onBlur={formikBag.handleBlur}
        helperText={
            form.errors.firstName &&
            form.touched.firstName &&
            String(form.errors.firstName)
        }
    />
    )}
/>
...