今天,我们发布了 Formik v3 alpha 的第一个版本。您可以使用以下命令安装它:
npm install formik@next
发布这篇博客文章的原因是,存在一个小的破坏性更改,由于其性质,我们不幸地无法像通常使用弃用通知那样向您发出警告。
但是,在进入坏消息之前,让我们先分享好消息。
parse
、format
和 formatOnBlur
属性!新的 alpha 版本包含用于 getFieldProps
、<Field>
和 useField()
的新 parse
、format
和 formatOnBlur
属性。这些属性使实现 输入掩码 变得容易得多——这是一种技术,您可以更改输入的原始值的格式,使其以某种方式显示给用户(例如,电话号码 (917) 555-1234 或文本日期 10/2020)。对于 TypeScript 用户,以下内容是新的
interface FieldConfig<V> {// ...omitted for brevity/*** Function to parse raw input value before setting it to state*/parse?: (rawInput: string, name: string) => V;/*** Function to transform value passed to input*/format?: (value: V, name: string) => any;/*** Should Formik wait until the blur event before formatting input value?* @default false*/formatOnBlur?: boolean;}// ...elsewhere...const [field] = useField({ name: 'phone', parse: rawInput => ... })<Field name="phone" parse={rawInput => ... } /><input {...formikProps.getFieldProps({ name: 'phone', parse: rawInput => ... }) />
这是一个使用 [format-string-by-pattern](https://npmjs.net.cn/package/format-string-by-pattern)
包创建各种电话号码输入掩码的完整示例。请注意,在第一个输入中,即使您输入 9999999999,输入的值(以及 Formik 的内部值)也是 999-999-9999。很酷!
*专业提示:我非常注重创建直观的 API,因此我意识到 parse
和 format
很难记住。我一直在使用/在脑子里说的技巧如下:“format”→听起来像“from”→“from Formik”→从 Formik 到输入。再说一次,这只是 alpha 版本,如果太令人困惑,我们将重命名它们。*
为了支持这种新行为,我们需要对 onChange
和 onBlur
处理程序在 formikProps.getFieldProps()
返回时如何工作进行破坏性更改,这随后也会影响 useField()
和 Field
。
过去,这些 onChange
和 onBlur
方法与 formikProps.handleChange
和 formikProps.handleBlur
相同(由 useFormik()
或 render prop <Formik>
或 withFormik
返回)。但是,从 3.0.0-next.0 开始,这些方法的行为分别有所不同。
当从 getFieldProps
、useField
或 <Field>
的 render prop 返回时,onChange
和 onBlur
现在已经作用域到给定的字段,并且现在可以接受 React 合成事件或任意值。它们不再像 handleChange
和 handleBlur
那样可以柯里化。
以下是一些关于什么有效、什么无效的更具体的示例……
仍然有效,但不支持 parse
、format
和 formatOnBlur
export const MyReactNativeForm = props => (<FormikinitialValues={{ email: '' }}onSubmit={values => console.log(values)}>{({ handleChange, handleBlur, handleSubmit, values }) => (<View><TextInputonChangeText={handleChange('email')} // curriedonBlur={handleBlur('email')} // curriedvalue={values.email}/><Button onPress={handleSubmit} title="Submit" /></View>)}</Formik>);
不再有效
export const MyTextField = props => {const [field] = useField(props);const onChange = e => {e.persist();if (e.target.value === 'foo') {// Using the curried version of onChange,// effectively equivalent to setFieldValue() no longer worksfield.onChange(props.name)('bar');} else {field.onChange(e);}};return <input {...field} onChange={onChange} />;};
但是您可以这样做……
export const MyTextField = props => {const [field] = useField(props);const onChange = e => {e.persist();if (e.target.value === 'foo') {// You can now just set the valuefield.onChange('bar');} else {// Or pass an eventfield.onChange(e);}};return <input {...field} onChange={onChange} />;};
通常,这种细微的更改不会导致主版本号增加,但因为我们不再知道您是在柯里化 onChange
方法还是实际上打算将字符串参数设置为值,所以我们无法发出警告来避免您出错。🤷♂️
Formik v3 的主要目标是提高性能、人体工程学和 a11y,但也从我们在 React hooks 方面做出的某些从未实现的假设中恢复过来(如上下文选择器)。不幸的是,为了达到我们的目标,还将需要进行一些其他的破坏性更改和/或引入新的组件到 Formik 系列中。计划是在未来几周内在 next
分支上推出这些更改,讨论命名一段时间,然后决定是将一些现有组件拆分为自己的包(类似于 prop-types
)还是编写代码修改来自动化迁移路径。无论哪种方式,Formik 都变得更快了……快了很多,这早就应该实现了。