摘要:所以還是印證那句話是組件渲染的唯一依據(jù)。所以對(duì)組件的進(jìn)行約束是創(chuàng)建一個(gè)健康組件的必要條件。這里我們約束屬性類(lèi)型為。使用方式運(yùn)行結(jié)果沒(méi)有錯(cuò)誤假如我們?cè)偌尤胍粋€(gè)子組件控制臺(tái)如預(yù)期報(bào)錯(cuò)自定義約束萬(wàn)物皆有其局限性。
日常扯淡前的廢話
上一篇我們介紹了React中State對(duì)象,說(shuō)到它是組件渲染的唯一依據(jù);當(dāng)然我們也可以認(rèn)為State是組件中的數(shù)據(jù)源之一,它保存著組件渲染的所有數(shù)據(jù)并且可以直接作用于組件的渲染。這里有兩個(gè)地方我們畫(huà)了所謂的重點(diǎn),因?yàn)橐及 ?66...
PropsProps是Facebook為React組件提供的另一個(gè)神級(jí)API。顧名思義,prop(property)就是屬性的意思;props呢就是properties,當(dāng)然是很多個(gè)屬性啦。因?yàn)榇笄澜缰忻總€(gè)事物不可能只有一個(gè)屬性,所以
處于人道主義考慮(扯淡...頭伸過(guò)來(lái)),React設(shè)計(jì)師就允許我們給組件設(shè)置很多很多的屬性,究竟有多多?當(dāng)然是看我們開(kāi)發(fā)者自己的心情咯。組件的Props類(lèi)似于DOM的attributes,隨便從某個(gè)網(wǎng)頁(yè)上inspect某個(gè)節(jié)點(diǎn)都能看到除了tag以外這個(gè)節(jié)點(diǎn)還掛載了很多別的東西,比如我們常用的class或者id都是節(jié)點(diǎn)的屬性。當(dāng)然React組件中Props的表現(xiàn)也相似。不過(guò)相對(duì)于普通DOM的屬性操作,React的屬性操作可以說(shuō)是優(yōu)雅萬(wàn)分,至于優(yōu)雅到什么程度,下面會(huì)有例子呈上。我們一步一步來(lái)!
首先看個(gè)例子:
創(chuàng)建組件。一個(gè)很簡(jiǎn)單的組件,用來(lái)顯示從props傳來(lái)的文字
import React, {Component} from "react"; class Show extends Component { render() { return ({this.props.content}
) } } export default Show;
使用組件
從例子中可以看到向組件Show添加一個(gè)屬性很便捷,寫(xiě)一個(gè)屬性名再賦值就行了(而如果DOM需要添加一個(gè)屬性的話則需要調(diào)用setAttribute方法,異常繁瑣)。其次,當(dāng)我們給組件添加了屬性之后,那么這些屬性就被掛載到組件的this.props中。因此這就是為什么我們可以在組件中通過(guò)this.props.content來(lái)獲取通過(guò)Props傳入的文字(而如果DOM需要獲取一個(gè)屬性的話則需要調(diào)用getAttribute方法)。我們看下實(shí)際效果:
當(dāng)然我們也可以在添加屬性的同時(shí)進(jìn)行簡(jiǎn)單的邏輯處理,我們改下Show組件使用方式:
看下實(shí)際效果:
簡(jiǎn)直神器...不過(guò)筆者在這里想強(qiáng)調(diào)下
不建議寫(xiě)復(fù)雜的邏輯。過(guò)于復(fù)雜的邏輯會(huì)降低代碼的可閱讀性,所以如果某個(gè)屬性值被添加前需要做很多的處理,請(qǐng)把邏輯封裝在一個(gè)方法里最后用處理結(jié)果進(jìn)行賦值即可,比如醬紫:
class App extends Component { createContent = () => { let result = 0; for (let i = 0; i <= 100; i++) { result += i; } return result; }; render() { return (); } } export default App;Welcome to React
這樣可以將節(jié)點(diǎn)和邏輯分離,增加可閱讀性而且代碼會(huì)顯得很優(yōu)雅。
Props與State有什么不同?開(kāi)頭有說(shuō)過(guò)State并不是組件的唯一數(shù)據(jù)源,當(dāng)然上面的例子也證明了這一點(diǎn)。然而,它們又有什么不同?
1,Props被保存在this.props中,State被保存在this.state中;獲取也如此。Props給我們帶來(lái)了什么?
2,State可以在組件中更新,而Props不可以。至于為什么,我們接下來(lái)會(huì)有解釋?zhuān)?br>3,State的更新會(huì)引發(fā)組件的重新渲染;Props的更新(從組件外)并不會(huì)引發(fā)該組件的重新渲染。因此如果想在Props被更新的同時(shí)引發(fā)渲染,那么就需要在componentwillreceiveprops中或者getDerivedStateFromProps中將更新后的Props同步給State,這樣可以觸發(fā)組件的重新渲染,其本質(zhì)還是借用State的力量。所以還是印證那句話:State是組件渲染的唯一依據(jù)。
從上面的例子中我們可以看出我們可以將組件之外的數(shù)據(jù)通過(guò)Props傳遞給組件,這一特性也同樣解決了父子組件之間通信的問(wèn)題:如果父組件想傳遞數(shù)據(jù)給子組件,那么就可以將所需要傳遞的數(shù)據(jù)通過(guò)Props傳遞給子組件,上面的例子寫(xiě)得很詳細(xì)。同樣,正是因?yàn)榻M件的Props大多都是父組件向子組件傳遞數(shù)據(jù)的通道,那么也就解釋了為什么在子組件中不能修改Props中數(shù)據(jù)的原因,因?yàn)閯e人傳給你的東西你改啥?出問(wèn)題誰(shuí)背鍋?所以筆者在這里強(qiáng)調(diào)一個(gè):不要在組件中更改Props!。因?yàn)槲覀冎苯有薷腜rops中基本類(lèi)型的時(shí)候React會(huì)自動(dòng)報(bào)錯(cuò),但是如果修改引用類(lèi)型的話比如向數(shù)組添加一個(gè)元素,React并不會(huì)報(bào)錯(cuò)因?yàn)榈刂窙](méi)變進(jìn)而導(dǎo)致組件運(yùn)行異常。
Props約束我們都知道JavaScript是一門(mén)弱類(lèi)型的語(yǔ)言,與強(qiáng)類(lèi)型語(yǔ)言比如Java不同,我們?cè)诙x一個(gè)變量的時(shí)候不會(huì)去聲明這個(gè)對(duì)象到底是整型還是浮點(diǎn)還是字符串等等...因此當(dāng)我們給組件添加屬性的時(shí)候很可能會(huì)引發(fā)組件運(yùn)行出錯(cuò),比如組件有個(gè)屬性叫l(wèi)ist,我們希望它是一個(gè)數(shù)組并且在組件中對(duì)其使用了forEach。但是另一個(gè)開(kāi)發(fā)人員引用這個(gè)組件的時(shí)候由于不清楚所以傳了一個(gè)數(shù)字,那么組件就掛了。所以對(duì)組件的Props進(jìn)行約束是創(chuàng)建一個(gè)健康組件的必要條件。
約束工具本來(lái)React庫(kù)中包含了屬性監(jiān)測(cè)的包,但是在某個(gè)版本被移除了(筆者記不清從哪個(gè)版本開(kāi)始)。不過(guò)我們?nèi)钥赏ㄟ^(guò)第三方包做同樣的事情 prop-types
類(lèi)型約束其實(shí)Props約束最需要解決的是類(lèi)型的約束,由于篇幅有限因此下面通過(guò)一個(gè)例子介紹下具體使用方法,詳情請(qǐng)點(diǎn)開(kāi)鏈接自行查閱文檔
1,首先安裝第三方包是必須的 npm install prop-types --save
2,在文件中引入 import PropTypes from "prop-types"
3,修改之前的例子
import React, {Component} from "react"; import PropTypes from "prop-types"; class Show extends Component { render() { return () } } Show.propTypes = { content: PropTypes.string }; export default Show;{this.props.content}
我們創(chuàng)建完組件后并且在export之前,使用字面量對(duì)象對(duì)組件的propTypes進(jìn)行賦值以確定該組件的Props類(lèi)型。這里我們約束content屬性類(lèi)型為string。假如我們傳入的數(shù)據(jù)是一個(gè)數(shù)組的話
那么運(yùn)行的結(jié)果就出錯(cuò)了:
index.js:2178 Warning: Failed prop type: Invalid prop `content` of type `array` supplied to `Show`, expected `string`."必需"約束
所謂的"必需"約束是指定組件必須要某個(gè)屬性,寫(xiě)法如下:
Show.propTypes = { content: PropTypes.string.isRequired };
這里表示Show組件必須要有content這個(gè)屬性。假如沒(méi)有呢?
index.js:2178 Warning: Failed prop type: The prop `content` is marked as required in `Show`, but its value is `undefined`.
自然在控制臺(tái)就有報(bào)錯(cuò)信息了。
子組件約束子組件約束主要是約束該組件的子組件有幾個(gè),假如我們規(guī)定該組件只能有一個(gè)子組件就可以這么寫(xiě):
import React, {Component} from "react"; import PropTypes from "prop-types"; class Show extends Component { render() { return ({this.props.children}) } } Show.propTypes = { children: PropTypes.element }; export default Show;
此時(shí)我們是對(duì)該組件的children進(jìn)行了約束,筆者認(rèn)為children是React的保留字所以我們?cè)诙xProps的時(shí)候不要使用children。
使用方式:
Hello World
運(yùn)行結(jié)果沒(méi)有錯(cuò)誤;
假如我們?cè)偌尤胍粋€(gè)子組件
Hello
World
控制臺(tái)如預(yù)期報(bào)錯(cuò):
Warning: Failed prop type: Invalid prop `children` of type `array` supplied to `Show`, expected a single ReactElement.自定義約束
萬(wàn)物皆有其局限性。假如包提供的所有約束條件中沒(méi)有我們所期望怎么辦?那就自己寫(xiě)一個(gè)自定義約束即可;寫(xiě)法如下:
import React, {Component} from "react"; class Show extends Component { render() { return ({this.props.custom}
) } } Show.propTypes = { custom: function (props, propName, componentName) { if (typeof(props[propName]) === "string") { if (!props[propName].startsWith("React")) { return new Error(`The prop ${propName} of Component ${componentName} is not start with "React"`) } } else { return new Error(`The prop ${propName} of Component ${componentName} is not a string object`) } } }; export default Show;
此時(shí)我們并不需要引入第三方庫(kù)了,不過(guò)寫(xiě)法和前面的用法一樣,只是字面量對(duì)象的值不是特定的類(lèi)型而是一個(gè)校驗(yàn)函數(shù),函數(shù)的第一個(gè)參數(shù)是該組件的props集;第二個(gè)參數(shù)是被該校驗(yàn)函數(shù)監(jiān)測(cè)的prop名字(此時(shí)是custom;第三個(gè)參數(shù)是該組件的名字);從代碼可以看出我們這個(gè)自定義約束的目的是監(jiān)測(cè)該組件的custom屬性值是否為字符串并且以React開(kāi)頭。首先我們添加正確的屬性值:
運(yùn)行正常;然后添加錯(cuò)誤的屬性值看看:
控制臺(tái)打印出了我們預(yù)設(shè)的提示信息:
Warning: Failed prop type: The prop custom of Component Show is not start with "React"
再者如果我們添加錯(cuò)誤的類(lèi)型值看看:
錯(cuò)誤信息正常打?。?/p>
Warning: Failed prop type: The prop custom of Component Show is not a string object
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/97690.html
摘要:首先賣(mài)個(gè)關(guān)子,下面我們一起來(lái)復(fù)習(xí)下小學(xué)還是初中的一枚數(shù)學(xué)知識(shí)。一旦更改了,會(huì)觸發(fā)組件的重新渲染。為了頁(yè)面渲染性能的考慮,有助于在中進(jìn)行比較并確定是否重新渲染。 概念引入 對(duì)于React來(lái)說(shuō), 沒(méi)有State就沒(méi)有頁(yè)面的渲染, 我們也將什么都看不到 咋一聽(tīng)怎么那么唬人?不過(guò)的確是這樣,正如標(biāo)題所言State是UI的靈魂。我們都知道React的核心思想之一是組件化,將頁(yè)面所展示的東西按一定...
摘要:官方對(duì)的介紹是意思就是提供了一種通過(guò)組件樹(shù)傳遞數(shù)據(jù)的方法,而無(wú)需在每個(gè)級(jí)別手動(dòng)傳遞。這也是基于重要物證哈哈實(shí)例使用學(xué)習(xí)技術(shù)最終是要有產(chǎn)出的。依然被視作一個(gè)組件,不過(guò)不同的是它的子組件必須是一個(gè)方法并且該方法接收當(dāng)前對(duì)象并最終返回一個(gè)節(jié)點(diǎn)。 拋轉(zhuǎn)引玉 通過(guò)上一篇的科普我們知道如果父節(jié)點(diǎn)需要向子節(jié)點(diǎn)傳遞數(shù)據(jù),那么就得通過(guò)Props來(lái)實(shí)現(xiàn);那么擺在我們眼前的就有一個(gè)問(wèn)題了:現(xiàn)有N個(gè)節(jié)點(diǎn)并且它...
摘要:基礎(chǔ)創(chuàng)建虛擬參數(shù)元素名稱(chēng),例如參數(shù)屬性集合,例如,,,從參數(shù)開(kāi)始,表示該元素的子元素,通常這些元素通過(guò)創(chuàng)建,文本文件可以直接插入嘻嘻哈哈這是渲染器,將元素渲染到頁(yè)面中。 React簡(jiǎn)介 FeceBook開(kāi)源的一套框架,專(zhuān)注于MVC的視圖V模塊。實(shí)質(zhì)是對(duì)V視圖的一種實(shí)現(xiàn)。 React框架的設(shè)計(jì)沒(méi)有過(guò)分依賴(lài)于某個(gè)環(huán)境,它自建一套環(huán)境,就是virtual DOM(虛擬DOM)。 提供基礎(chǔ)AP...
摘要:深入系列,深入講解了中的重點(diǎn)概念特性和模式等,旨在幫助大家加深對(duì)的理解,以及在項(xiàng)目中更加靈活地使用。下篇預(yù)告深入系列組件的生命周期我的新書(shū)進(jìn)階之路已上市,請(qǐng)大家多多支持鏈接京東當(dāng)當(dāng) React 深入系列,深入講解了React中的重點(diǎn)概念、特性和模式等,旨在幫助大家加深對(duì)React的理解,以及在項(xiàng)目中更加靈活地使用React。 React 的核心思想是組件化的思想,而React 組件的定...
閱讀 3715·2021-10-18 13:34
閱讀 2405·2021-08-11 11:15
閱讀 1205·2019-08-30 15:44
閱讀 694·2019-08-26 10:32
閱讀 992·2019-08-26 10:13
閱讀 2067·2019-08-23 18:36
閱讀 1780·2019-08-23 18:35
閱讀 526·2019-08-23 17:10