您好,登錄后才能下訂單哦!
下載地址:
https://codesandbox.io/s/zKrK5YLDZ
案例Basics主要介紹Formik的基本用法,我想在前面幾篇的基礎(chǔ)上著重分析一下其核心API及數(shù)據(jù)結(jié)構(gòu)的使用思路。
我的開發(fā)環(huán)境為MAC+WebStorm(2017.2) ,案例Basics的架構(gòu)如下圖所示:
工程的運(yùn)行前,需要先安裝系統(tǒng)有關(guān)依賴:
npm install
然后,編譯運(yùn)行:
npm start
運(yùn)行結(jié)果如codesandbox.io上的結(jié)果一致:
本示例核心文件主要是index.js,其主要代碼架構(gòu)如下四部分組件:
// 一)、必要的import依賴導(dǎo)入
import './helper.css';
import { MoreResources, DISPLAY_FORMIK_STATE } from './helper';
import React from 'react';,
import { render } from 'react-dom';
import { withFormik } from 'formik';
import Yup from 'yup';
// 二)、表單組件定義,后面將使用Formik({..}) API進(jìn)一步包裝
const MyInnerForm = props => {
const {
......
} = props;
return (
<form onSubmit={handleSubmit}>
......
</form>
);
};
//三)、使用Formik進(jìn)一步包裝上面定義的表單組件
const EnhancedForm = withFormik({
......
})(MyInnerForm);
const App = () => (
<div className="app">
......
<EnhancedForm />
<MoreResources />
</div>
);
//四)、表單渲染到結(jié)果設(shè)備
render(<App />, document.getElementById('root'));
第一部分關(guān)鍵代碼是表單組件定義,如下所示:
const MyInnerForm = props => {
const { values, touched, errors, dirty, isSubmitting,handleChange, handleBlur, handleSubmit, handleReset, } = props;
return (
<form onSubmit={handleSubmit}>
<label htmlFor="email" style={{ display: 'block' }}> Email</label>
<input id="email" placeholder="Enter your email" type="text"
value={values.email}
onChange={handleChange}
onBlur={handleBlur}
className={errors.email && touched.email ? 'text-input error' : 'text-input'}
/>
{errors.email &&
touched.email && <div className="input-feedback">{errors.email}</div>}
<button type="button" className="outline" onClick={handleReset} disabled={!dirty || isSubmitting} >
Reset
</button>
<button type="submit" disabled={isSubmitting}>
Submit
</button>
<DisplayFormikState {...props} />
</form>
);
};
表單定義使用了ES6箭頭函數(shù)語(yǔ)法格式??雌饋恚瑥?lt;form>元素到<input>及<button>等都是使用原始的HTML5元素表達(dá)方式(當(dāng)然,其中也加入了JSX語(yǔ)法格式)。正如本系列文章前面多處重復(fù)強(qiáng)調(diào)的,我們還是多對(duì)比redux-form來理解Formik運(yùn)行原理效果更好。
于是,關(guān)鍵首先集中在下面的問題:
對(duì)于上述問題的回答要看接下來的withFormik這個(gè)API對(duì)于上面表單組件的調(diào)用方式。完全回答了這兩個(gè)問題,內(nèi)部組成表單各字段內(nèi)容的表達(dá)方面就易于理解了。
封裝表單組件的代碼如下:
const EnhancedForm = withFormik({
mapPropsToValues: () => ({ email: '' }),
validationSchema: Yup.object().shape({
email: Yup.string()
.email('Invalid email address')
.required('Email is required!'),
}),
handleSubmit: (values, { setSubmitting }) => {
setTimeout(() => {
alert(JSON.stringify(values, null, 2));
setSubmitting(false);
}, 1000);
},
displayName: 'BasicForm', // helps with React DevTools
})(MyInnerForm);
對(duì)于withFormik(options)這個(gè)API中各參數(shù)的解釋在本系列前文中已經(jīng)有詳細(xì)注釋,在此再重點(diǎn)強(qiáng)調(diào)幾點(diǎn)。
(1)displayName參數(shù)是為便于調(diào)試使用的一個(gè)唯一字符串標(biāo)記;
(2)對(duì)于參數(shù)mapPropsToValues要作一下詳細(xì)解說。如果指定了這個(gè)選項(xiàng),F(xiàn)ormik會(huì)把這個(gè)函數(shù)的執(zhí)行結(jié)果(典型情況下會(huì)返回一個(gè)對(duì)象,本例中正是如此)轉(zhuǎn)換成可更新的表單狀態(tài),并且使這個(gè)結(jié)果可以在新組件中進(jìn)行訪問(訪問形式是props.values)。如果沒有指定這個(gè)選項(xiàng),F(xiàn)ormik會(huì)把所有不是函數(shù)的屬性內(nèi)容映射到內(nèi)部組件的props.values。也就是說,如果你忽略這個(gè)參數(shù),F(xiàn)ormik將僅傳遞不是函數(shù)的屬性內(nèi)容(where typeof props[k] !== 'function',其中k是某種鍵)。需要說明的是,即使你的表單沒有從其父組件中接收任何屬性,你也可以使用mapPropsToValues來把你的表單初始化成空狀態(tài)。
(3)參數(shù)validationSchema定義了一個(gè)Yup模式(開源Yup庫(kù),是Formik作者也是本人認(rèn)為在使用Formik過程中優(yōu)先選擇使用的校驗(yàn)工具——如果你有良好的ES6基礎(chǔ),你會(huì)發(fā)現(xiàn)這個(gè)校驗(yàn)工具比較全面且直觀易用)。本例中用于校驗(yàn)電子郵件的格式并給出可能的錯(cuò)誤提示。
(4)handleSubmit是表單提交處理器函數(shù)。其中,values是要提交的表單數(shù)據(jù);setSubmitting是handleSubmit的參數(shù)FormikBag中的一種取值,這里把setSubmitting的參數(shù)設(shè)置為false,意指當(dāng)前表單并未正處于提交狀態(tài)(因?yàn)檫@里僅使用簡(jiǎn)單的模擬方式來演示提交),并且會(huì)導(dǎo)致isSubmitting屬性的值為false。
接下來的代碼比較簡(jiǎn)單了:
const App = () => (
<div className="app">
<h2>
<a target="_blank" rel="noopener">
Formik
</a>{' '}
基礎(chǔ)示例
</h2>
<EnhancedForm />
<MoreResources />
</div>
);
render(<App />, document.getElementById('root'));
把EnhancedForm作為一個(gè)普通React組件加入到系統(tǒng)父組件中,并通過調(diào)用react-dom庫(kù)的render方式隨著父組件一起渲染我們的表單組件。
另外,上面代碼中的簡(jiǎn)單組件MoreResources定義于另一個(gè)獨(dú)立文件中,用于展示官方的其他鏈接示例。有關(guān)代碼非常簡(jiǎn)單,在此不再贅述。
有了對(duì)上面withFormik(options)這個(gè)高階組件API中各個(gè)參數(shù)含義的理解,再來看最前面定義表單組件部分的代碼(相對(duì)于redux-form實(shí)現(xiàn)邏輯)就簡(jiǎn)單多了。
類似于redux-form表單參數(shù)中的props,既包含了對(duì)象和字符串參數(shù),也有函數(shù)形式的屬性參數(shù)。至于各個(gè)參數(shù)的作用,請(qǐng)參考前面的幾篇短文中的相關(guān)解釋。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。