福米克和 Material-UI
Formik and Material-UI
我正在尝试将 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 组件。
我认为您不需要另一个库,甚至不需要创建自己的包装器,我认为您需要稍微调整一下代码。
您遇到的一个问题是您没有在 Material TextField 中传递 onChange 函数,因此 firstName 的表单值始终为 null,因此您总是会收到错误消息,即使您输入了姓名。
尝试在您的 TextField 和 onChange 函数上添加名称或 ID,如下所示:
<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)
}
/>
)}
/>
如评论中所述,实现 "wrapper" 组件实际上可能是个好主意,就像他们在 Formik 或 ReactFinalForm 的示例中所做的那样:
- https://github.com/stackworx/formik-material-ui/tree/master/src
- https://github.com/final-form/react-final-form#material-ui-10
想法是一样的:实现自定义 "wrapper" 组件来包装 Material-UI 组件并映射 Formik 或 ReactFinalForm APIs 道具。
这种方法的优点是将两个框架之间的映射集中在一个地方,这样你就不用每次都重复映射,如果其中一个框架引入了破坏性的变化,你只需要改变那些自定义的"wrapper" 个组件。
你可以试试这个: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 将继续按预期处理验证,并将呈现 Material UI 组件和错误消息。其他 Mui 输入组件的文档中还有其他详细信息,可帮助进行自定义。
在此处查看 <Field />
的 formik 文档:https://jaredpalmer.com/formik/docs/api/field
例如,您可以使用 Material 的 OutlinedInput 来设置您的输入样式:
<Field as={OutlinedInput} />
如果您需要将更多道具传递给 OutlinedInput,只需将它们添加到 Field,它就会将它们传递给 OutlinedInput:
<Field as={OutlinedInput} color="primary" InputProps={{ startAdornment: <InputAdornment position="start"><AccountCircle /></InputAdornment> }} />
要使用 material-ui 和 formik,您可以使用 官方 formik 文档:
https://formik.org/docs/examples/with-material-ui
您可以使用 setFieldValue 方法 对于创建自定义输入更改处理程序很有用
<Formik
initialValues={{
name: "",
}}
onSubmit={(values: any) => console.log(values)}
>
{({ handleSubmit, setFieldValue }) => (
<Form noValidate autoComplete="off" onSubmit={handleSubmit}>
<TextField
onChange={(event) => setFieldValue("name", event.target.value)}
type="text"
label="Name"
/>
</Form>
)}
</Formik>
我正在尝试将 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 组件。
我认为您不需要另一个库,甚至不需要创建自己的包装器,我认为您需要稍微调整一下代码。
您遇到的一个问题是您没有在 Material TextField 中传递 onChange 函数,因此 firstName 的表单值始终为 null,因此您总是会收到错误消息,即使您输入了姓名。 尝试在您的 TextField 和 onChange 函数上添加名称或 ID,如下所示:
<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)
}
/>
)}
/>
如评论中所述,实现 "wrapper" 组件实际上可能是个好主意,就像他们在 Formik 或 ReactFinalForm 的示例中所做的那样:
- https://github.com/stackworx/formik-material-ui/tree/master/src
- https://github.com/final-form/react-final-form#material-ui-10
想法是一样的:实现自定义 "wrapper" 组件来包装 Material-UI 组件并映射 Formik 或 ReactFinalForm APIs 道具。
这种方法的优点是将两个框架之间的映射集中在一个地方,这样你就不用每次都重复映射,如果其中一个框架引入了破坏性的变化,你只需要改变那些自定义的"wrapper" 个组件。
你可以试试这个: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 将继续按预期处理验证,并将呈现 Material UI 组件和错误消息。其他 Mui 输入组件的文档中还有其他详细信息,可帮助进行自定义。
在此处查看 <Field />
的 formik 文档:https://jaredpalmer.com/formik/docs/api/field
例如,您可以使用 Material 的 OutlinedInput 来设置您的输入样式:
<Field as={OutlinedInput} />
如果您需要将更多道具传递给 OutlinedInput,只需将它们添加到 Field,它就会将它们传递给 OutlinedInput:
<Field as={OutlinedInput} color="primary" InputProps={{ startAdornment: <InputAdornment position="start"><AccountCircle /></InputAdornment> }} />
要使用 material-ui 和 formik,您可以使用 官方 formik 文档: https://formik.org/docs/examples/with-material-ui
您可以使用 setFieldValue 方法 对于创建自定义输入更改处理程序很有用
<Formik
initialValues={{
name: "",
}}
onSubmit={(values: any) => console.log(values)}
>
{({ handleSubmit, setFieldValue }) => (
<Form noValidate autoComplete="off" onSubmit={handleSubmit}>
<TextField
onChange={(event) => setFieldValue("name", event.target.value)}
type="text"
label="Name"
/>
</Form>
)}
</Formik>