溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Formik官方應(yīng)用案例解析(一)Basics

發(fā)布時(shí)間:2020-06-04 11:40:05 來源:網(wǎng)絡(luò) 閱讀:3321 作者:googlingman 欄目:web開發(fā)

一、說明



下載地址:
https://codesandbox.io/s/zKrK5YLDZ

案例Basics主要介紹Formik的基本用法,我想在前面幾篇的基礎(chǔ)上著重分析一下其核心API及數(shù)據(jù)結(jié)構(gòu)的使用思路。

二、示例架構(gòu)

我的開發(fā)環(huán)境為MAC+WebStorm(2017.2) ,案例Basics的架構(gòu)如下圖所示:
Formik官方應(yīng)用案例解析(一)Basics

工程的運(yùn)行前,需要先安裝系統(tǒng)有關(guān)依賴:
npm install

然后,編譯運(yùn)行:
npm start

運(yùn)行結(jié)果如codesandbox.io上的結(jié)果一致:
Formik官方應(yīng)用案例解析(一)Basics

三、核心文件主要組成

本示例核心文件主要是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)鍵首先集中在下面的問題:

(1)參數(shù)props是誰(shuí)提供的(即這個(gè)表單組件定義在哪里調(diào)用)?

(2)參數(shù)props包含了哪些內(nèi)容?

對(duì)于上述問題的回答要看接下來的withFormik這個(gè)API對(duì)于上面表單組件的調(diào)用方式。完全回答了這兩個(gè)問題,內(nèi)部組成表單各字段內(nèi)容的表達(dá)方面就易于理解了。

(二)使用Formik包裝表單組件

封裝表單組件的代碼如下:

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)解釋。

向AI問一下細(xì)節(jié)

免責(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)容。

AI