您好,登錄后才能下訂單哦!
本文將繼續我學習redux-form的總結部分,在這一部分中,我將對官方示例SelectingFormValuesForm給出簡要解析,不當處還希望同志們批評指正。
本示例原意重在介紹formValueSelector這個redux-form API的用法的。官文上說,在我們的表單中有時候想訪問表單中另外一些字段值時可以使用這個API。不過,要使用這個formValueSelector API,我們需要使用connect方法把表單中的有關字段值直接連接到Redux store上。
但是,官方還提出警告:要小心使用上面這個API,因為每當表單中有關字段值改變時整個表單都會重新渲染,從而影響系統性能。
在redux-demo的大多數示例中,關鍵代碼都在于表單(也是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
上面代碼的關鍵點并不多。第一,注意import語句導入的connect方法,還有reduxForm和formValueSelector兩個方法的導入。
第二,接下來通過“let SelectingFormValuesForm=props=>{...}”語句定義表單SelectingFormValuesForm。注意它的剪頭函數的參數props中除了系統內置的屬性和方法定義外,還加入了定制的三個屬性(vavoriateColorValue,fullName和hasEmailValue)的定義。
formValueSelector API的直接使用,主要體現在如下幾句代碼中:
// 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)
易見,上面代碼中第一行創建了一個selector函數,這是通過調用API formValueSelector實現的,傳遞的參數是經過上面reduxForm封裝的容器表單SelectingFormValuesForm(注意,上面為了偷懶,創建表單的變量名與由reduxForm方法返回的表單包裝以后的對象名是一樣的——這是經包裝以后的對象,實際上也是一個容器組件)。觀察源碼的話,你會注意到reduxForm方法內部重點調用了connect方法。
有關connect方法的作用,文后的參考中已作了詳細的分析,主要有兩點:
(1)此方法的作用在把React組件與Redux store連接到一起。
(2)此方法沒有修改傳入的React組件,而返回一個新的已經與Redux store連接的組件。
接下來再往下看,上面代碼中接著顯式調用connect方法,此方法的第一個參數通常命名為mapStateToPros,意即把系統Store中的state轉換成各組件能夠訪問的props。在上面代碼中,通過調用了前面剛剛創建的selector函數(兩個參數含義明顯,略述),得到state中存儲的對應內容的一個副本。特別注意下面一句:
const { firstName, lastName } = selector(state, 'firstName', 'lastName')
這里通過ES6的解構賦值,一次性取得一組值。最后,此函數(connect的第一個參數)返回一個新的對象,注意到對象的前兩個鍵值與鍵重名(ES6特性),第三個鍵則是一個新生成的鍵名。
可以看出,上面return語句返回的對象的各個屬性正對應于上面表單組件定義時props提供的幾個自定制屬性。這幾個數據是怎么告訴給表單組件的呢?這要歸功于connect()方法。
connect()方法是react-redux庫的核心方法之一,典型使用在定義包括上面的表單組件在內的容器組件的模塊中,而且可以多次嵌套式地使用,具體情形則根據需要而定。
總起來講,是否使用本文提供的API formValueSelector,請謹記本文前提加粗的官方提醒的一句,不是非用不可,而是用巧了可以簡單編碼,在多表單多字段情況下用不好則導致影響系統性能!
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/
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。