今天,我們發布了 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://www.npmjs.com/package/format-string-by-pattern)
套件來建立各種電話號碼輸入遮罩。請注意,在第一個輸入中,即使您輸入 9999999999,輸入的值(以及 Formik 的內部值)也是 999-999-9999。很俐落!
*專業提示:我一直致力於打造直觀的 API,所以我意識到 parse
和 format
很難記住。我一直在使用/在腦海中默念的訣竅如下:「format」→ 聽起來像「from」→「from Formik」→ 從 Formik 到輸入。再次強調,這是一個 alpha 版本,所以如果太令人困惑,我們會重新命名這些。*
為了支援這個新行為,我們需要對 formikProps.getFieldProps()
返回的 onChange
和 onBlur
事件處理程式的運作方式進行重大變更,這隨後也會影響 useField()
和 Field
。
過去,這些 onChange
和 onBlur
方法與 formikProps.handleChange
和 formikProps.handleBlur
(由 useFormik()
或渲染屬性 <Formik>
或 withFormik
返回)相同。但是,從 3.0.0-next.0 開始,這些方法的行為分別不同。
當從 getFieldProps
、useField
或 <Field>
的渲染屬性返回時,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 的主要目標是提高效能、人體工學和無障礙性,同時也從我們圍繞 React hooks 做出的一些從未實現的賭注中恢復過來(例如上下文選擇器)。遺憾的是,為了達到我們的目標,Formik 系列將需要引入一些更重大的變更和/或新的元件。我們的計畫是在接下來的幾週內在 next
分支上推出這些變更,討論一下命名,然後決定是將一些現有元件拆分到它們自己的套件中(例如 prop-types
),還是編寫程式碼修改器來自動化遷移路徑。無論哪種方式,Formik 都將變得更快......快很多很多,這是早就應該做的事情。