作者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://www.npmjs.com/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 版本,所以如果太令人困惑,我們會重新命名這些。*

重大變更

為了支援這個新行為,我們需要對 formikProps.getFieldProps() 返回的 onChangeonBlur 事件處理程式的運作方式進行重大變更,這隨後也會影響 useField()Field

過去,這些 onChangeonBlur 方法與 formikProps.handleChangeformikProps.handleBlur(由 useFormik() 或渲染屬性 <Formik>withFormik 返回)相同。但是,從 3.0.0-next.0 開始,這些方法的行為分別不同。

當從 getFieldPropsuseField<Field> 的渲染屬性返回時,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 的主要目標是提高效能、人體工學和無障礙性,同時也從我們圍繞 React hooks 做出的一些從未實現的賭注中恢復過來(例如上下文選擇器)。遺憾的是,為了達到我們的目標,Formik 系列將需要引入一些更重大的變更和/或新的元件。我們的計畫是在接下來的幾週內在 next 分支上推出這些變更,討論一下命名,然後決定是將一些現有元件拆分到它們自己的套件中(例如 prop-types),還是編寫程式碼修改器來自動化遷移路徑。無論哪種方式,Formik 都將變得更快......快很多很多,這是早就應該做的事情。

訂閱我們的電子報

最新的 Formik 新聞、文章和資源,將會發送到您的收件匣。

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