React.js 小書 Lesson24 - PropTypes 和組件參數(shù)驗(yàn)證
轉(zhuǎn)載請(qǐng)注明出處疚顷,保留原文鏈接以及作者信息
在線閱讀:http://huziketang.com/books/react
我們來了到了一個(gè)非常尷尬的章節(jié)菠净,很多初學(xué)的朋友可能對(duì)這一章的知識(shí)點(diǎn)不屑一顧亥揖,覺得用不用對(duì)程序功能也沒什么影響淤击。但其實(shí)這一章節(jié)的知識(shí)在你構(gòu)建多人協(xié)作程奠、大型的應(yīng)用程序的時(shí)候也是非常重要的宣脉,不可忽視宁昭。
都說 JavaScript 是一門靈活的語言 —— 這就是像是說“你是個(gè)好人”一樣喷市,凡事都有背后沒有說出來的話相种。JavaScript 的靈活性體現(xiàn)在弱類型、高階函數(shù)等語言特性上品姓。而語言的弱類型一般來說確實(shí)讓我們寫代碼很爽寝并,但是也很容易出 bug。
變量沒有固定類型可以隨意賦值腹备,在我們構(gòu)建大型應(yīng)用程序的時(shí)候并不是什么好的事情衬潦。你寫下了 let a = {}
,如果這是個(gè)共享的狀態(tài)并且在某個(gè)地方把 a = 3
植酥,那么 a.xxx
就會(huì)讓程序崩潰了镀岛。而這種非常隱晦但是低級(jí)的錯(cuò)誤在強(qiáng)類型的語言例如 C/C++、Java 中是不可能發(fā)生的友驮,這些代碼連編譯都不可能通過漂羊,也別妄圖運(yùn)行。
大型應(yīng)用程序的構(gòu)建其實(shí)更適合用強(qiáng)類型的語言來構(gòu)建卸留,它有更多的規(guī)則走越,可以幫助我們?cè)诰帉懘a階段、編譯階段規(guī)避掉很多問題耻瑟,讓我們的應(yīng)用程序更加的安全旨指。JavaScript 早就脫離了玩具語言的領(lǐng)域并且投入到大型的應(yīng)用程序的生產(chǎn)活動(dòng)中捻悯,因?yàn)樗娜躅愋停3R馕吨皇呛馨踩倜K越陙沓霈F(xiàn)了類似 TypeScript 和 Flow 等技術(shù),來彌補(bǔ) JavaScript 這方面的缺陷算柳。
React.js 的組件其實(shí)是為了構(gòu)建大型應(yīng)用程序而生低淡。但是因?yàn)?JavaScript 這樣的特性,你在編寫了一個(gè)組件以后瞬项,根本不知道別人會(huì)怎么使用你的組件蔗蹋,往里傳什么亂七八糟的參數(shù),例如評(píng)論組件:
class Comment extends Component {
const { comment } = this.props
render () {
return (
<div className='comment'>
<div className='comment-user'>
<span>{comment.username} </span>:
</div>
<p>{comment.content}</p>
</div>
)
}
}
但是別人往里面?zhèn)饕粋€(gè)數(shù)字你拿他一點(diǎn)辦法都沒有:
<Comment comment={1} />
JavaScript 在這種情況下是不會(huì)報(bào)任何錯(cuò)誤的囱淋,但是頁面就是顯示不正常猪杭,然后我們踏上了漫漫 debug 的路程。這里的例子還是過于簡(jiǎn)單妥衣,容易 debug皂吮,但是對(duì)于比較復(fù)雜的成因和情況是比較難處理的。
于是 React.js 就提供了一種機(jī)制税手,讓你可以給組件的配置參數(shù)加上類型驗(yàn)證蜂筹,就用上述的評(píng)論組件例子,你可以配置 Comment
只能接受對(duì)象類型的 comment
參數(shù)芦倒,你傳個(gè)數(shù)字進(jìn)來組件就強(qiáng)制報(bào)錯(cuò)艺挪。
import React, { Component, PropTypes } from 'react'
class Comment extends Component {
static propTypes = {
comment: PropTypes.object
}
render () {
const { comment } = this.props
return (
<div className='comment'>
<div className='comment-user'>
<span>{comment.username} </span>:
</div>
<p>{comment.content}</p>
</div>
)
}
}
注意我們?cè)谖募^部引入了 PropTypes
,并且給 Comment
組件類添加了類屬性 propTypes
兵扬,里面的內(nèi)容的意思就是你傳入的 comment
類型必須為 object
(對(duì)象)麻裳。
這時(shí)候如果再往里面?zhèn)魅霐?shù)字,瀏覽器就會(huì)報(bào)錯(cuò):
[圖片上傳失敗...(image-f2c9a7-1510227000171)]
出錯(cuò)信息明確告訴我們:你給 Comment
組件傳了一個(gè)數(shù)字類型的 comment
器钟,而它應(yīng)該是 object
津坑。你就清晰知道問題出在哪里了。
雖然 propTypes
幫我們指定了參數(shù)類型傲霸,但是并沒有說這個(gè)參數(shù)一定要傳入国瓮,事實(shí)上,這些參數(shù)默認(rèn)都是可選的狞谱∧四。可選參數(shù)我們可以通過配置 defaultProps
,讓它在不傳入的時(shí)候有默認(rèn)值跟衅。但是我們這里并沒有配置 defaultProps
孵睬,所以如果直接用 <Comment />
而不傳入任何參數(shù)的話,comment
就會(huì)是 undefined
伶跷,comment.username
會(huì)導(dǎo)致程序報(bào)錯(cuò):
[圖片上傳失敗...(image-3c0073-1510227000171)]
這個(gè)出錯(cuò)信息并不夠友好掰读。我們可以通過 isRequired
關(guān)鍵字來強(qiáng)制組件某個(gè)參數(shù)必須傳入:
...
static propTypes = {
comment: PropTypes.object.isRequired
}
...
那么會(huì)獲得一個(gè)更加友好的出錯(cuò)信息秘狞,查錯(cuò)會(huì)更方便:
[圖片上傳失敗...(image-12c395-1510227000171)]
React.js 提供的 PropTypes
提供了一些列的數(shù)據(jù)類型可以用來配置組件的參數(shù):
PropTypes.array
PropTypes.bool
PropTypes.func
PropTypes.number
PropTypes.object
PropTypes.string
PropTypes.node
PropTypes.element
...
更多類型及其用法可以參看官方文檔: Typechecking With PropTypes - React。
組件參數(shù)驗(yàn)證在構(gòu)建大型的組件庫(kù)的時(shí)候相當(dāng)有用蹈集,可以幫助我們迅速定位這種類型錯(cuò)誤烁试,讓我們組件開發(fā)更加規(guī)范。另外也起到了一個(gè)說明文檔的作用拢肆,如果大家都約定都寫 propTypes
减响,那你在使用別人寫的組件的時(shí)候,只要看到組件的 propTypes
就清晰地知道這個(gè)組件到底能夠接受什么參數(shù)郭怪,什么參數(shù)是可選的支示,什么參數(shù)是必選的。
總結(jié)
通過 PropTypes
給組件的參數(shù)做類型限制鄙才,可以在幫助我們迅速定位錯(cuò)誤颂鸿,這在構(gòu)建大型應(yīng)用程序的時(shí)候特別有用;另外攒庵,給組件加上 propTypes
嘴纺,也讓組件的開發(fā)、使用更加規(guī)范清晰浓冒。
這里建議大家寫組件的時(shí)候盡量都寫 propTypes
颖医,有時(shí)候有點(diǎn)麻煩,但是是值得的裆蒸。
下一節(jié)中我們將介紹《React.js 小書 Lesson25 - 實(shí)戰(zhàn)分析:評(píng)論功能(四)》熔萧。