溫馨提示×

溫馨提示×

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

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

redux-form(V7.4.2)筆記(四)SelectingFormValuesForm實例解析

發(fā)布時間:2020-07-12 10:36:06 來源:網(wǎng)絡(luò) 閱讀:1161 作者:googlingman 欄目:web開發(fā)

本文將繼續(xù)我學(xué)習(xí)redux-form的總結(jié)部分,在這一部分中,我將對官方示例SelectingFormValuesForm給出簡要解析,不當(dāng)處還希望同志們批評指正。

示例SelectingFormValuesForm簡介

本示例原意重在介紹formValueSelector這個redux-form API的用法的。官文上說,在我們的表單中有時候想訪問表單中另外一些字段值時可以使用這個API。不過,要使用這個formValueSelector API,我們需要使用connect方法把表單中的有關(guān)字段值直接連接到Redux store上。

但是,官方還提出警告:要小心使用上面這個API,因為每當(dāng)表單中有關(guān)字段值改變時整個表單都會重新渲染,從而影響系統(tǒng)性能。

示例中有關(guān)代碼分析

在redux-demo的大多數(shù)示例中,關(guān)鍵代碼都在于表單(也是react-redux容器)
定義部分。下面給出表單SelectingFormValuesForm的定義代碼:

SelectingFormValuesForm.js
import React from 'react'
import { connect } from 'react-redux'
import { Field, reduxForm, formValueSelector } from 'redux-form'

let SelectingFormValuesForm = props => {
  const {
    favoriteColorValue,
    fullName,
    handleSubmit,
    hasEmailValue,
    pristine,
    reset,
    submitting
  } = props
  return (
    <form onSubmit={handleSubmit}>
      <div>
        <label>First Name</label>
        <div>
          <Field
            name="firstName"
            component="input"
            type="text"
            placeholder="First Name"
          />
        </div>
      </div>
      <div>
        <label>Last Name</label>
        <div>
          <Field
            name="lastName"
            component="input"
            type="text"
            placeholder="Last Name"
          />
        </div>
      </div>
      <div>
        <label htmlFor="hasEmail">Has Email?</label>
        <div>
          <Field
            name="hasEmail"
            id="hasEmail"
            component="input"
            type="checkbox"
          />
        </div>
      </div>
      {hasEmailValue && (
        <div>
          <label>Email</label>
          <div>
            <Field
              name="email"
              component="input"
              type="email"
              placeholder="Email"
            />
          </div>
        </div>
      )}
      <div>
        <label>Favorite Color</label>
        <div>
          <Field name="favoriteColor" component="select">
            <option />
            <option value="#ff0000">Red</option>
            <option value="#00ff00">Green</option>
            <option value="#0000ff">Blue</option>
          </Field>
        </div>
      </div>
      {favoriteColorValue && (
        <div
          style={{
            height: 80,
            width: 200,
            margin: '10px auto',
            backgroundColor: favoriteColorValue
          }}
        />
      )}
      <div>
        <button type="submit" disabled={pristine || submitting}>
          Submit {fullName}
        </button>
        <button type="button" disabled={pristine || submitting} onClick={reset}>
          Clear Values
        </button>
      </div>
    </form>
  )
}

// The order of the decoration does not matter.

// Decorate with redux-form
SelectingFormValuesForm = reduxForm({
  form: 'selectingFormValues' // a unique identifier for this form
})(SelectingFormValuesForm)

// Decorate with connect to read form values
const selector = formValueSelector('selectingFormValues') // <-- same as form name
SelectingFormValuesForm = connect(state => {
  // can select values individually
  const hasEmailValue = selector(state, 'hasEmail')
  const favoriteColorValue = selector(state, 'favoriteColor')
  // or together as a group
  const { firstName, lastName } = selector(state, 'firstName', 'lastName')
  return {
    hasEmailValue,
    favoriteColorValue,
    fullName: `${firstName || ''} ${lastName || ''}`
  }
})(SelectingFormValuesForm)

export default SelectingFormValuesForm

上面代碼的關(guān)鍵點并不多。第一,注意import語句導(dǎo)入的connect方法,還有reduxForm和formValueSelector兩個方法的導(dǎo)入。

第二,接下來通過“l(fā)et SelectingFormValuesForm=props=>{...}”語句定義表單SelectingFormValuesForm。注意它的剪頭函數(shù)的參數(shù)props中除了系統(tǒng)內(nèi)置的屬性和方法定義外,還加入了定制的三個屬性(vavoriateColorValue,fullName和hasEmailValue)的定義。

API函數(shù)的使用

formValueSelector API的直接使用,主要體現(xiàn)在如下幾句代碼中:

// Decorate with connect to read form values
const selector = formValueSelector('selectingFormValues') // <-- same as form name
SelectingFormValuesForm = connect(state => {
  // can select values individually
  const hasEmailValue = selector(state, 'hasEmail')
  const favoriteColorValue = selector(state, 'favoriteColor')
  // or together as a group
  const { firstName, lastName } = selector(state, 'firstName', 'lastName')
  return {
    hasEmailValue,
    favoriteColorValue,
    fullName: `${firstName || ''} ${lastName || ''}`
  }
})(SelectingFormValuesForm)

易見,上面代碼中第一行創(chuàng)建了一個selector函數(shù),這是通過調(diào)用API formValueSelector實現(xiàn)的,傳遞的參數(shù)是經(jīng)過上面reduxForm封裝的容器表單SelectingFormValuesForm(注意,上面為了偷懶,創(chuàng)建表單的變量名與由reduxForm方法返回的表單包裝以后的對象名是一樣的——這是經(jīng)包裝以后的對象,實際上也是一個容器組件)。觀察源碼的話,你會注意到reduxForm方法內(nèi)部重點調(diào)用了connect方法。
有關(guān)connect方法的作用,文后的參考中已作了詳細的分析,主要有兩點:
(1)此方法的作用在把React組件與Redux store連接到一起。
(2)此方法沒有修改傳入的React組件,而返回一個新的已經(jīng)與Redux store連接的組件。

接下來再往下看,上面代碼中接著顯式調(diào)用connect方法,此方法的第一個參數(shù)通常命名為mapStateToPros,意即把系統(tǒng)Store中的state轉(zhuǎn)換成各組件能夠訪問的props。在上面代碼中,通過調(diào)用了前面剛剛創(chuàng)建的selector函數(shù)(兩個參數(shù)含義明顯,略述),得到state中存儲的對應(yīng)內(nèi)容的一個副本。特別注意下面一句:

const { firstName, lastName } = selector(state, 'firstName', 'lastName')

這里通過ES6的解構(gòu)賦值,一次性取得一組值。最后,此函數(shù)(connect的第一個參數(shù))返回一個新的對象,注意到對象的前兩個鍵值與鍵重名(ES6特性),第三個鍵則是一個新生成的鍵名。

可以看出,上面return語句返回的對象的各個屬性正對應(yīng)于上面表單組件定義時props提供的幾個自定制屬性。這幾個數(shù)據(jù)是怎么告訴給表單組件的呢?這要歸功于connect()方法。

補充

connect()方法是react-redux庫的核心方法之一,典型使用在定義包括上面的表單組件在內(nèi)的容器組件的模塊中,而且可以多次嵌套式地使用,具體情形則根據(jù)需要而定。

小結(jié)

總起來講,是否使用本文提供的API formValueSelector,請謹記本文前提加粗的官方提醒的一句,不是非用不可,而是用巧了可以簡單編碼,在多表單多字段情況下用不好則導(dǎo)致影響系統(tǒng)性能!

參考資料

1.http://taobaofed.org/blog/2016/08/18/react-redux-connect/
2.https://www.jianshu.com/p/9873d4ccb891
3.https://github.com/lipeishang/react-redux-connect-demo/blob/master/public/src/containers/App.js
4.https://segmentfault.com/a/1190000010416732
5.https://redux-form.com/7.4.2/docs/gettingstarted.md/

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI