webentwicklung-frage-antwort-db.com.de

Formik und Material-UI

Ich versuche Formik mit dem Textfeld "Material-UI" zu verwenden. So wie:

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;

Ich möchte, dass Formik für die Validierung und die Material-UI für Looks verantwortlich ist. Ich möchte errors.firstName an die TextField-Komponente übergeben, der Fehler wird jedoch nicht richtig angezeigt. Wie kann ich das Problem beheben, damit es immer noch lesbar ist? Ich möchte nicht meine eigene TextField-Komponente schreiben ... oder vielleicht gibt es eine andere beliebte Bibliothek für Formulare?

3
Adam Marczyk

Wie in Kommentaren erwähnt, kann es tatsächlich eine gute Idee sein, "Wrapper" -Komponenten zu implementieren, wie in diesen Beispielen von Formik oder ReactFinalForm:

Die Idee ist die gleiche: Implementieren Sie benutzerdefinierte "Wrapper" -Komponenten, um Material-UI-Komponenten einzubinden und Formik- oder ReactFinalForm-API-Requisiten zuzuordnen.

Die Vorteile dieses Ansatzes bestehen darin, die Zuordnung zwischen den beiden Frameworks an einer Stelle zu zentralisieren, so dass Sie das Mapping nicht jedes Mal wiederholen. Wenn eines der Frameworks brechende Änderungen einführt, müssen Sie nur diese benutzerdefinierten Wrapper-Komponenten ändern.

7
Ricovitch

Ich denke nicht, dass Sie eine andere Bibliothek benötigen oder gar Ihren eigenen Wrapper erstellen. Ich denke, Sie müssen Ihren Code ein wenig durchforsten. 

Ein Problem, das Sie haben, ist, dass Sie keine onChange-Funktion im Material TextField übergeben, sodass der Formularwert von firstName immer null ist und Sie immer den Fehler erhalten, auch wenn Sie einen Namen eingegeben haben oder id in Ihrem TextField und eine onChange-Funktion wie folgt: 

<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)
        }
    />
    )}
/>
3
needsleep

Sie können dies versuchen: https://github.com/daixianceng/formik-material-fields

Installation:

npm install --save formik-material-fields

Verwendungszweck:

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>
    );
  }
}
1
Cosmo Dai

Sie können auch diese Bibliothek ausprobieren, die das Schwergewicht für Sie übernimmt und den Wrapper-Code für Material-UI-Komponenten implementiert (einschließlich <TextField />): https://github.com/stackworx/formik-material-ui .

Installation:

yarn add formik-material-ui

Übergeben Sie in Ihrer Formik-Formularkomponente das <TextField /> Komponente als Komponentenstütze der Formik <Field /> Komponente.

import { Formik, Field, Form } from 'formik';
import { TextField } from 'formik-material-ui';

<Field
  name="email"
  label="Email"
  type="email"
  component={TextField}
/>

Formik wird die Validierung weiterhin wie erwartet durchführen und die Material-UI-Komponente und die Fehlermeldung anzeigen. In den Dokumenten finden Sie zusätzliche Informationen zu anderen Mui-Eingabekomponenten und zur Unterstützung der Anpassung.

0
whitehall