Material-UIテキストフィールドでFormikを使用しようとしています。そのようです:
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が外観を担当します。 errors.firstNameをTextFieldコンポーネントに渡したいのですが、エラーが正しく表示されません。読みやすいように修正するにはどうすればよいですか?独自のTextFieldコンポーネントを書きたくありません。
コメントで言及したように、FormikまたはReactFinalFormのこのサンプルで行ったように、実際には「ラッパー」コンポーネントを実装することをお勧めします。
考え方は同じです。カスタム「ラッパー」コンポーネントを実装して、Material-UIコンポーネントをラップし、FormikまたはReactFinalForm APIの小道具をマップします。
このアプローチの利点は、2つのフレームワーク間のマッピングを1か所に集中させることです。これにより、毎回マッピングを繰り返す必要がなくなります。
別のライブラリが必要なわけではなく、独自のラッパーを作成する必要もないと思います。コードを少し調整する必要があると思います。
ある問題の1つは、onChange関数をMaterial TextFieldに渡さないため、firstNameのフォーム値が常にnullであるため、名前を入力した場合でも常にエラーが発生することです。 TextFieldに名前またはIDを追加し、次のように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)
}
/>
)}
/>
これを試すことができます: 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>
);
}
}
また、このライブラリを試すこともできます。このライブラリは、あなたのために重労働を行い、Material-UIコンポーネントのラッパーコードを実装します(<TextField />
): https://github.com/stackworx/formik-material-ui 。
インストール:
yarn add formik-material-ui
Formikフォームコンポーネントで、<TextField />
Formikのコンポーネント支柱としてのコンポーネント<Field />
コンポーネント。
import { Formik, Field, Form } from 'formik';
import { TextField } from 'formik-material-ui';
<Field
name="email"
label="Email"
type="email"
component={TextField}
/>
Formikは引き続き検証を処理し、マテリアルUIコンポーネントとエラーメッセージをレンダリングします。ドキュメントには、他のMui入力コンポーネントに関する追加の詳細があり、カスタマイズを支援します。