您好,登錄后才能下訂單哦!
下載地址:
https://codesandbox.io/s/zKrK5YLDZ
案例Basics主要介紹Formik的基本用法,我想在前面幾篇的基礎上著重分析一下其核心API及數據結構的使用思路。
我的開發環境為MAC+WebStorm(2017.2) ,案例Basics的架構如下圖所示:
工程的運行前,需要先安裝系統有關依賴:
npm install
然后,編譯運行:
npm start
運行結果如codesandbox.io上的結果一致:
本示例核心文件主要是index.js,其主要代碼架構如下四部分組件:
// 一)、必要的import依賴導入
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進一步包裝
const MyInnerForm = props => {
const {
......
} = props;
return (
<form onSubmit={handleSubmit}>
......
</form>
);
};
//三)、使用Formik進一步包裝上面定義的表單組件
const EnhancedForm = withFormik({
......
})(MyInnerForm);
const App = () => (
<div className="app">
......
<EnhancedForm />
<MoreResources />
</div>
);
//四)、表單渲染到結果設備
render(<App />, document.getElementById('root'));
第一部分關鍵代碼是表單組件定義,如下所示:
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箭頭函數語法格式。看起來,從<form>元素到<input>及<button>等都是使用原始的HTML5元素表達方式(當然,其中也加入了JSX語法格式)。正如本系列文章前面多處重復強調的,我們還是多對比redux-form來理解Formik運行原理效果更好。
于是,關鍵首先集中在下面的問題:
對于上述問題的回答要看接下來的withFormik這個API對于上面表單組件的調用方式。完全回答了這兩個問題,內部組成表單各字段內容的表達方面就易于理解了。
封裝表單組件的代碼如下:
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);
對于withFormik(options)這個API中各參數的解釋在本系列前文中已經有詳細注釋,在此再重點強調幾點。
(1)displayName參數是為便于調試使用的一個唯一字符串標記;
(2)對于參數mapPropsToValues要作一下詳細解說。如果指定了這個選項,Formik會把這個函數的執行結果(典型情況下會返回一個對象,本例中正是如此)轉換成可更新的表單狀態,并且使這個結果可以在新組件中進行訪問(訪問形式是props.values)。如果沒有指定這個選項,Formik會把所有不是函數的屬性內容映射到內部組件的props.values。也就是說,如果你忽略這個參數,Formik將僅傳遞不是函數的屬性內容(where typeof props[k] !== 'function',其中k是某種鍵)。需要說明的是,即使你的表單沒有從其父組件中接收任何屬性,你也可以使用mapPropsToValues來把你的表單初始化成空狀態。
(3)參數validationSchema定義了一個Yup模式(開源Yup庫,是Formik作者也是本人認為在使用Formik過程中優先選擇使用的校驗工具——如果你有良好的ES6基礎,你會發現這個校驗工具比較全面且直觀易用)。本例中用于校驗電子郵件的格式并給出可能的錯誤提示。
(4)handleSubmit是表單提交處理器函數。其中,values是要提交的表單數據;setSubmitting是handleSubmit的參數FormikBag中的一種取值,這里把setSubmitting的參數設置為false,意指當前表單并未正處于提交狀態(因為這里僅使用簡單的模擬方式來演示提交),并且會導致isSubmitting屬性的值為false。
接下來的代碼比較簡單了:
const App = () => (
<div className="app">
<h2>
<a target="_blank" rel="noopener">
Formik
</a>{' '}
基礎示例
</h2>
<EnhancedForm />
<MoreResources />
</div>
);
render(<App />, document.getElementById('root'));
把EnhancedForm作為一個普通React組件加入到系統父組件中,并通過調用react-dom庫的render方式隨著父組件一起渲染我們的表單組件。
另外,上面代碼中的簡單組件MoreResources定義于另一個獨立文件中,用于展示官方的其他鏈接示例。有關代碼非常簡單,在此不再贅述。
有了對上面withFormik(options)這個高階組件API中各個參數含義的理解,再來看最前面定義表單組件部分的代碼(相對于redux-form實現邏輯)就簡單多了。
類似于redux-form表單參數中的props,既包含了對象和字符串參數,也有函數形式的屬性參數。至于各個參數的作用,請參考前面的幾篇短文中的相關解釋。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。