在React中进行Formik表单验证

时间:2019-11-14 10:53:51

标签: formik

我已经使用formik实现了表单验证并做出反应。我正在使用Material-UI。

   <Formik
    initialValues={{ name: '' }}
    onSubmit={values => {
        console.log('submitting', values);
    }}
    validate={values => {
        alert();
        let errors = {};
        if (!values.name) {
            errors.name = 'Name is required';
        }
        return errors;
    }}>

    {({
        handleSubmit,
        handleChange,
        values,
        errors
    }) => (
            <form onSubmit={handleSubmit}>
                <div>
                    <input name="name"
                        onChange={handleChange}
                        name="name"
                        value={values.name}
                        type="text"
                        placeholder="Name">
                    </input>
                    {errors.name &&
                        <span style={{ color: "red", fontWeight: "bold" }}>
                            {errors.name}
                        </span>
                    }
                </div>
                <div>
                    <button>Submit</button>
                </div>
            </form>

        )}
</Formik>

上面的代码对于正常的输入标签工作正常,但是对于选择 TextField 材质小部件不起作用。

材质UI是否存在兼容性问题? 请帮忙。

1 个答案:

答案 0 :(得分:0)

正如Chris B.所说,解决方案是将每个所需的元素包装在具有Formik要求的React组件内。对于Material-UI,Gerhat on GitHub has created some of those components

您可以通过从上面的github链接下载源代码来使用它们。那里还有一个用法示例,展示了如何将Gerhat的“包装器”用于Material TextField和Select。

在Gerhat的用法示例中,TextField是该github存储库中的组件;它不是Material UI TextField直接;它是Material TextField小部件周围与Formik兼容的“包装器”。

通过查看gerhat的源代码,您可以学习如何对所需的其他Material部件执行相同的操作。


但是,对于初学者来说,gerhat的实现可能不是最容易的。这些包装器很容易使用,但是从该代码中可能并不明显为其他小部件或组件编写 own 包装器。

See my answer here讨论Formik的<Field>useField。这些是“包装”现有React组件的简便方法。 (不是Material-UI小部件,而是AFAIK,您可以像其他任何React组件一样包装它们。)


如果您想了解gerhat的方法,以下是有关您将在github上看到的代码的一些注释。

This is the source to TextField.jsx in that repo

TextField.jsx的“心脏”是环绕Material的TextField的。在这些行中可以看到生成的virtual-DOM元素(代表Material TextField):

return (
    <TextField
      label={label}
      error={hasError}
      helperText={hasError ? errorText : ''}
      {...field}
      {...other}
    />
  )

有关如何使其与Formik兼容的详细信息,请参见上面的源链接。恕我直言,需要对React和Formik都有相当高级的了解,以了解在那里正在做什么。这就是为什么我提到FielduseField作为编写自己的“与Formik兼容的包装器”的起点的原因。

我将提及一个细节。该实现依靠与index.js相同文件夹中的文件TextField.jsx来将TextField.jsx的默认值FTextField映射到名称TextField,这是您在此答案开头在“用法”代码中如何引用它的方式。 SO Q&A about index.js file of a React component

index.js内容:

export { default as TextField } from './TextField'

TextField源文件夹中的其他两个文件是“ .d.ts”文件。 See this Q&A了解这些内容。除非您正在使用TypeScript,否则不需要它们。