typescript Formik 和 Material-UI
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/52111447/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Formik and Material-UI
提问by n3stle
I am trying to use Formik with Material-UI text field. Like so:
我正在尝试将 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;
I want Formik to be responsible for validation and Material-UI for looks. I want to pass errors.firstName to TextField component but the error doesn't display correctly. How can I fix it so it still will be clear to read? I don't want to write my own TextField component.
我希望 Formik 负责外观的验证和 Material-UI。我想将 errors.firstName 传递给 TextField 组件,但错误无法正确显示。我该如何修复它才能让它仍然清晰可读?我不想编写自己的 TextField 组件。
回答by needsleep
I don't think you need another library or even create your own wrapper, I think you need to tweek your code a bit.
我认为您不需要另一个库,甚至不需要创建自己的包装器,我认为您需要稍微修改一下代码。
One problem you have is that you don't pass an onChange function in the Material TextField so the form value of firstName is always null and so you always get the error, even if you have entered a name. Try adding a name or id on your TextField and an onChange function like so:
您遇到的一个问题是您没有在 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)
}
/>
)}
/>
回答by Ricovitch
As mentionned in comments, it may actually be a good idea to implement "wrapper" components, like they did in this samples from Formik or ReactFinalForm :
正如评论中提到的,实现“包装器”组件实际上可能是一个好主意,就像他们在来自 Formik 或 ReactFinalForm 的示例中所做的那样:
- https://github.com/stackworx/formik-material-ui/tree/master/src
- https://github.com/final-form/react-final-form#material-ui-10
- https://github.com/stackworx/formik-material-ui/tree/master/src
- https://github.com/final-form/react-final-form#material-ui-10
The idea is the same : implement custom "wrapper" components to wrap Material-UI components and map Formik or ReactFinalForm APIs props.
想法是一样的:实现自定义“包装器”组件来包装 Material-UI 组件并映射 Formik 或 ReactFinalForm API 道具。
The advantages of this approach is to centralize in one place the mapping between the two frameworks, so that you do not repeat the mapping each time, and if one of the framework introduces breaking changes you just have to change those custom "wrapper" components.
这种方法的优点是将两个框架之间的映射集中在一个地方,这样您就不会每次都重复映射,如果其中一个框架引入了破坏性更改,您只需更改那些自定义“包装器”组件。
回答by Cosmo Dai
You can try this: https://github.com/daixianceng/formik-material-fields
你可以试试这个:https: //github.com/daixianceng/formik-material-fields
Installation:
安装:
npm install --save formik-material-fields
Usage:
用法:
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>
);
}
}
回答by whitehall
You could also try this library, which does the heavy-lifting for you and implements the wrapper code around Material-UI components (including <TextField />
): https://github.com/stackworx/formik-material-ui.
你也可以试试这个库,它为你做了繁重的工作,并围绕 Material-UI 组件(包括<TextField />
)实现了包装器代码:https: //github.com/stackworx/formik-material-ui。
Installation:
安装:
yarn add formik-material-ui
In your Formik form component, pass the <TextField />
component as the component prop of the Formik <Field />
component.
在您的 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 will continue to handle the validation as expected and will render the Material UI component and error message. There are additional details in the docs for other Mui input components and to aid with customization.
Formik 将继续按预期处理验证,并将呈现 Material UI 组件和错误消息。其他 Mui 输入组件的文档中还有其他详细信息,以帮助进行自定义。
回答by ben
Check out the formik docs for <Field />
here: https://jaredpalmer.com/formik/docs/api/field
<Field />
在此处查看 formik 文档:https: //jaredpalmer.com/formik/docs/api/field
As an example you could use Material's OutlinedInput to style your input:
例如,您可以使用 Material 的 OutlinedInput 来设置输入的样式:
<Field as={OutlinedInput} />