Formik 和 Material-UI
2018-08-31
48256
我正在尝试将 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 负责外观。 我想将 errors.firstName 传递给 TextField 组件,但错误无法正确显示。我该如何修复它,以便仍然清晰易读?我不想编写自己的 TextField 组件。
3个回答
我认为您不需要另一个库,甚至不需要创建自己的包装器,我认为您需要稍微调整一下代码。
您遇到的一个问题是,您没有在 Material TextField 中传递 onChange 函数,因此 firstName 的表单值始终为空,因此您总是会收到错误,即使您输入了名称。 尝试在您的 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)
}
/>
)}
/>
needsleep
2018-09-02
正如评论中提到的,实现“包装器”组件可能实际上是一个好主意,就像他们在 Formik 或 ReactFinalForm 的示例中所做的那样:
- https://github.com/stackworx/formik-material-ui/tree/master/src
- https://github.com/final-form/react-final-form#material-ui-10
想法是一样的:实现自定义“包装器”组件来包装 Material-UI 组件并映射 Formik 或 ReactFinalForm API 属性。
这种方法的优点是集中在一个地方两个框架之间的映射,这样您就不必每次都重复映射,并且如果其中一个框架引入了重大更改,您只需更改那些自定义的“包装器”组件即可。
Ricovitch
2018-09-07
你可以试试这个: https://github.com/daixianeng/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>
);
}
}
Cosmo Dai
2018-12-12