作者Jared Palmer
2020年10月27日

Formik 3 Alpha

今天,我们发布了 Formik v3 alpha 的第一个版本。您可以使用以下命令安装它:

npm install formik@next

发布这篇博客文章的原因是,存在一个小的破坏性更改,由于其性质,我们不幸地无法像通常使用弃用通知那样向您发出警告。


但是,在进入坏消息之前,让我们先分享好消息。

新的 parseformatformatOnBlur 属性!

新的 alpha 版本包含用于 getFieldProps<Field>useField() 的新 parseformatformatOnBlur 属性。这些属性使实现 输入掩码 变得容易得多——这是一种技术,您可以更改输入的原始值的格式,使其以某种方式显示给用户(例如,电话号码 (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。很酷!

https://codesandbox.io/s/github/jaredpalmer/formik/tree/next/examples/format-string-by-pattern?fontsize=14&hidenavigation=1&theme=dark&file=/index.js

*专业提示:我非常注重创建直观的 API,因此我意识到 parseformat 很难记住。我一直在使用/在脑子里说的技巧如下:“format”→听起来像“from”→“from Formik”→从 Formik 到输入。再说一次,这只是 alpha 版本,如果太令人困惑,我们将重命名它们。*

破坏性更改

为了支持这种新行为,我们需要对 onChangeonBlur 处理程序在 formikProps.getFieldProps() 返回时如何工作进行破坏性更改,这随后也会影响 useField()Field

过去,这些 onChangeonBlur 方法与 formikProps.handleChangeformikProps.handleBlur 相同(由 useFormik() 或 render prop <Formik>withFormik 返回)。但是,从 3.0.0-next.0 开始,这些方法的行为分别有所不同。

当从 getFieldPropsuseField<Field> 的 render prop 返回时,onChangeonBlur 现在已经作用域到给定的字段,并且现在可以接受 React 合成事件或任意值。它们不再像 handleChangehandleBlur 那样可以柯里化。

一些示例

以下是一些关于什么有效、什么无效的更具体的示例……

仍然有效,但不支持 parseformatformatOnBlur

export const MyReactNativeForm = props => (
<Formik
initialValues={{ email: '' }}
onSubmit={values => console.log(values)}
>
{({ handleChange, handleBlur, handleSubmit, values }) => (
<View>
<TextInput
onChangeText={handleChange('email')} // curried
onBlur={handleBlur('email')} // curried
value={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 works
field.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 value
field.onChange('bar');
} else {
// Or pass an event
field.onChange(e);
}
};
return <input {...field} onChange={onChange} />;
};

通常,这种细微的更改不会导致主版本号增加,但因为我们不再知道您是在柯里化 onChange 方法还是实际上打算将字符串参数设置为值,所以我们无法发出警告来避免您出错。🤷‍♂️

接下来是什么?

Formik v3 的主要目标是提高性能、人体工程学和 a11y,但也从我们在 React hooks 方面做出的某些从未实现的假设中恢复过来(如上下文选择器)。不幸的是,为了达到我们的目标,还将需要进行一些其他的破坏性更改和/或引入新的组件到 Formik 系列中。计划是在未来几周内在 next 分支上推出这些更改,讨论命名一段时间,然后决定是将一些现有组件拆分为自己的包(类似于 prop-types)还是编写代码修改来自动化迁移路径。无论哪种方式,Formik 都变得更快了……快了很多,这早就应该实现了。

订阅我们的新闻通讯

最新的 Formik 新闻、文章和资源,发送到您的收件箱。

版权所有 © 2020 Formium, Inc. 保留所有权利。