React基礎(chǔ)-核心概念

一缎罢、props

1崇棠、什么是props?

定義:props是父子組件之間通信的紐帶哆档,它表示的是父組件傳遞過(guò)來(lái)的自定義屬性和children插佛。

props是一個(gè)對(duì)象,通過(guò)props可以訪問(wèn)到父組件傳遞過(guò)來(lái)的自定義屬性和children。

props是只讀的(不能修改它)

通過(guò)props渡讼,可以向子組件傳遞ReactNode(ReactElement混驰、基本數(shù)據(jù)類型、數(shù)組映皆、JSX對(duì)象)、普通對(duì)象、函數(shù)等韧衣。

2假残、React的兩種組件

什么組件?組件就是一個(gè)段可以被復(fù)用代碼塊抹竹。組件化的意義:封裝快速開發(fā)。

進(jìn)一步理解組件:組件實(shí)際就是一個(gè)“函數(shù)”痢艺,它接收props作為入?yún)⒒粒祷赜糜谝晥D渲染的JSX元素。因?yàn)閜rops是只讀的喳整,所以每一個(gè)React組件都是一個(gè)“純函數(shù)”。(什么是純函數(shù)?入?yún)⒉荒芨模o相同入?yún)r(shí)總是返回唯一的結(jié)果躬充。)

提示:雖然props不能修改,但可以參與業(yè)務(wù)邏輯運(yùn)算。

(一)函數(shù)式組件(無(wú)狀態(tài)組件)

const Hello = (props) => (<div></div>)

特點(diǎn):它只有props梳杏,沒有state狀態(tài),也沒有this斑鸦、生命周期诫钓、ref场梆、上下文等特性。所以它的性能較好。

提示:自 React v16.8 以后端逼,我們可以通過(guò) Hooks API 來(lái)模擬上述缺失的React特性而昨。

(二)類組件(有狀態(tài)組件)

class Hello extends React.Component { // this.props }

特點(diǎn):它有props漆改,也有state狀態(tài)唆铐、this、生命周期筛婉、ref、上下文等特性粱栖。相對(duì)于函數(shù)式組件其性能較差。

提示:自 React v16.8 以后渠退,類組件越來(lái)越少使用了≈ぞ牛現(xiàn)在市場(chǎng)中主流是Hooks+函數(shù)式組件猜惋。

3私股、父子組件

什么是 props.children 偿曙?它代表是自定義組件內(nèi)部所嵌套的ReactNode列表。

在自定義屬性時(shí)喧笔,不要把屬性名命名為 children牌借,因?yàn)樗刑厥夂x晒旅。

在props.children向子組件傳遞children時(shí)硕淑,建議傳遞ReactNode列表寥袭,不要傳遞普通數(shù)據(jù)抓韩。如果要傳遞數(shù)據(jù),建議使用自定義props苍日。

4拦耐、父子組件通信:父?jìng)髯邮褂米远x屬性,子傳父通過(guò)自定義事件疗琉。(從Vue的角度來(lái)理解父子組件)

父組件給的props如果是“普通數(shù)據(jù)”坚俗,用于渲染恩闻、用于邏輯操作。

父組件給的props如果是“函數(shù)”剧董,在子組件中可調(diào)用并向父組件返回?cái)?shù)據(jù)幢尚。

父組件給的props如果“JSX對(duì)象”,在子組件中直接參與渲染翅楼。

5尉剩、props是“組件化(組合)”的語(yǔ)法基礎(chǔ)。

二毅臊、state

1理茎、描述

state 是React組件自身的數(shù)據(jù),具有“響應(yīng)式”的特性(當(dāng)state變量被this.setState()修改時(shí)管嬉,視圖會(huì)自動(dòng)更新)皂林。

這里的“響應(yīng)式”和vue響應(yīng)式是完全不同的,React中沒有“數(shù)據(jù)支持宠蚂、依賴收集”等工作式撼。

1、定義state

在類組件中才有state(函數(shù)式組件中沒有state)求厕,必須在constructor這個(gè)生命周期中定義state著隆。

state必須“先定義扰楼、再使用”。state變量一般是基本數(shù)據(jù)類型美浦、數(shù)組弦赖、普通對(duì)象。不能定義其它的數(shù)據(jù)類型浦辨。

2蹬竖、使用state

在類組件中,使用this.state來(lái)訪問(wèn)所有的state變量流酬。

3币厕、state的特點(diǎn)

當(dāng)使用this.setState()這個(gè)專屬方法來(lái)修改state時(shí),這會(huì)觸發(fā)render()運(yùn)行并返回新的“Fiber”芽腾,進(jìn)一步執(zhí)行“協(xié)調(diào)運(yùn)行”(找到最小化的臟節(jié)點(diǎn)集合)旦装,最后一次“提交”更新DOM。

state是當(dāng)前組件的“自有數(shù)據(jù)”摊滔,可以通過(guò)props傳遞給后代組件阴绢,但不能傳遞給父組件。這就是React中“單向數(shù)據(jù)流”(自上而下)艰躺。

4呻袭、如何優(yōu)雅地修改state變量?

修改state變量必須使用this.setState()這個(gè)專屬方法腺兴。不要直接修改state左电,因?yàn)橹苯有薷膕tate不會(huì)觸發(fā)render()。

每次修改state時(shí)都要考慮“新值與舊值是否有”页响,如果有關(guān)使用this.setState(fn,callback)這種語(yǔ)法券腔,如果無(wú)關(guān)使用this.setState({},callback)這種語(yǔ)法。

示例:this.setState({name:'GP8'}) this.setState(state=>({count:state.count+1}))

5拘泞、this.setState()異步性

在合成事件(on*開頭的系列事件、生命周期鉤子)中枕扫,this.setState()是異步的陪腌。

在微任務(wù)函數(shù)體中(Promise.then)中,this.setState()是同步的烟瞧。

在非合成事件中(定時(shí)器诗鸭、DOM事件)中,this.setState()是同步的参滴。

this.setState() 為什么默認(rèn)是異步强岸?

因?yàn)殚_發(fā)者在同一個(gè)“合成事件”中有可能多次調(diào)用this.setState(),如果它同步的砾赔,這會(huì)導(dǎo)致多次render()蝌箍,這顯然是一種性能損耗青灼。所以,React在設(shè)計(jì)this.setState()把它變成異步的妓盲,這樣的好處是更好保證this.setState()的淺合并杂拨,以節(jié)省性能。

什么是合成事件悯衬?

on*事件處理器弹沽、生命周期鉤子都是合成事件。合成事件是React官方專門封裝一組API筋粗,這些合成事件是“可控的”策橘,React就可以放心地把合成事件中的this.setState()變成異步的,目的是為了對(duì)多個(gè)this.setState()進(jìn)行淺合并娜亿,以節(jié)省性能丽已。

this.setState()在合成事件中是異步的。那我們?nèi)绾沃肋@個(gè)異步任務(wù)完成了暇唾?

方案一:this.setState(fn|{}, callback) 在callback被調(diào)用時(shí)就說(shuō)明這個(gè)異步工作完成了促脉。

方案二:componentDidUpdate() 當(dāng)這個(gè)生命周期被觸發(fā)時(shí),說(shuō)明這個(gè)異步工作完成了策州。

建議:React官方建議瘸味,方案二更靠譜,方案一盡量少用够挂。

測(cè)試this.setState()的同步性:在非合成事件中旁仿,它都是同步的。如果一定要給個(gè)解釋孽糖,React無(wú)法操控“非合成事件”枯冈,所以沒有辦法把this.setState()變成異步的,所以也不存在性能優(yōu)化办悟。

場(chǎng)景一:在定時(shí)器中尘奏,this.setState()是同步的。

場(chǎng)景二:用dom病蛉、ref的方式綁定事件炫加,在事件處理器中,this.setState()也是同步的铺然。

場(chǎng)景三:在new Promise().then()中俗孝,this.setState()是同步的。(異議:后面再用真實(shí)ajax測(cè)試)

6魄健、this.setState() 淺合并

理解:在同一個(gè)更新周期(合成事件)中赋铝,如果多次調(diào)用this.setState(),React會(huì)自動(dòng)將它們合并沽瘦,以節(jié)省性能革骨。

三农尖、事件

事件綁定原則:盡可能地使用合成事件來(lái)綁定事件。

合成事件:https://zh-hans.reactjs.org/docs/events.html

1苛蒲、如何綁定事件卤橄?

語(yǔ)法一:使用ES5的方式來(lái)綁定事件 onClick={this.handle.bind(this)}

語(yǔ)法二:使用ES6的方式來(lái)綁定事件 onClick={()=>this.handle()}

建議:使用“語(yǔ)法二”來(lái)綁定事件

2、如何拿到事件對(duì)象臂外?

ES5方式綁定事件窟扑,事件處理器的最后一個(gè)參數(shù)永遠(yuǎn)都事件對(duì)象。

ES6方式綁定事件漏健,需要手動(dòng)傳遞事件對(duì)象嚎货。

3、事件處理器如何自定義傳遞參數(shù)蔫浆?

ES5方式事件傳參殖属,onClick={this.handle.bind(this, 'arg', ...)}

ES6方式事件傳參,onClick={ev=>this.handle('arg', ev)}

4瓦盛、如何阻止冒泡洗显、默認(rèn)事件?

用事件對(duì)象的api來(lái)實(shí)現(xiàn)(二階段的知識(shí))

ev.stopPropagation()

ev.preventDefault()

5原环、如何監(jiān)聽鍵盤事件挠唆?

用事件對(duì)象的api來(lái)實(shí)現(xiàn)(二階段的知識(shí))?ev.keyCode

四、條件渲染

條件渲染:元素的顯示與隱藏嘱吗,這里巧用的都是JSX語(yǔ)法玄组。

1、單一元素的條件渲染

語(yǔ)法:{ bol && <jsx> }

2谒麦、兩個(gè)元素的條件渲染

語(yǔ)法: { bol ? <jsx1> : <jsx2> }

3俄讹、多個(gè)元素的條件渲染

語(yǔ)法:建議封裝“自定義的渲染函數(shù)” function renderThing() { return <jsx> }

4、動(dòng)態(tài)class

語(yǔ)法:className={'類名的拼接'}

5绕德、動(dòng)態(tài)style

語(yǔ)法:style={ css樣式的鍵值對(duì) }

五患膛、列表渲染

列表渲染:React官方建議使用map()進(jìn)行渲染

語(yǔ)法基礎(chǔ):JSX支持對(duì)數(shù)組的渲染。

為什么官方建議使用map()方法來(lái)實(shí)現(xiàn)列表渲染耻蛇?

語(yǔ)法:const newList = list.map(fn)剩瓶,

特點(diǎn):map()方法的特點(diǎn),對(duì)源數(shù)據(jù)進(jìn)行fn處理城丧,返回一個(gè)新的jsx數(shù)組。

六豌鹤、表單綁定

表單綁定:除了文件上傳以外亡哄,都要使用受控表單。

1布疙、兩類表單

受控表單蚊惯,表單/類表單的value或checked由state控制著愿卸。

非受控表單,表單/類表單的value或checked與state完全無(wú)關(guān)截型。

原則:除了文件上傳以外趴荸,所有表單都必須是受控表單。

對(duì)于普通文本表單宦焦、select表單发钝,用value屬性來(lái)受控,用onChange取值波闹。

對(duì)于radio/checkbox表單酝豪,用checked屬性來(lái)受控,用onChange取值精堕。

對(duì)于自定義的“類表單”孵淘,我們建議用自定義屬性value來(lái)受控,用自定義onChange取值歹篓。

2瘫证、表單的單向綁定

意思是在React中表單的取值操作必須手動(dòng)完成。

最佳實(shí)踐:當(dāng)頁(yè)面中表單特別多時(shí)庄撮,我們只封裝一個(gè)change handler來(lái)取所有表單的值背捌。也就是對(duì)change handler方法的復(fù)用。復(fù)用的方式有很多重窟,可以自定義dataset载萌、自定義事件傳參來(lái)實(shí)現(xiàn)。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末巡扇,一起剝皮案震驚了整個(gè)濱河市扭仁,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌厅翔,老刑警劉巖乖坠,帶你破解...
    沈念sama閱讀 218,941評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異刀闷,居然都是意外死亡熊泵,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門甸昏,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)顽分,“玉大人,你說(shuō)我怎么就攤上這事施蜜∽湔海” “怎么了?”我有些...
    開封第一講書人閱讀 165,345評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)缸沃。 經(jīng)常有香客問(wèn)我恰起,道長(zhǎng),這世上最難降的妖魔是什么趾牧? 我笑而不...
    開封第一講書人閱讀 58,851評(píng)論 1 295
  • 正文 為了忘掉前任检盼,我火速辦了婚禮,結(jié)果婚禮上翘单,老公的妹妹穿的比我還像新娘吨枉。我一直安慰自己,他們只是感情好县恕,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評(píng)論 6 392
  • 文/花漫 我一把揭開白布东羹。 她就那樣靜靜地躺著,像睡著了一般忠烛。 火紅的嫁衣襯著肌膚如雪属提。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,688評(píng)論 1 305
  • 那天美尸,我揣著相機(jī)與錄音冤议,去河邊找鬼。 笑死师坎,一個(gè)胖子當(dāng)著我的面吹牛恕酸,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播胯陋,決...
    沈念sama閱讀 40,414評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼蕊温,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了遏乔?” 一聲冷哼從身側(cè)響起义矛,我...
    開封第一講書人閱讀 39,319評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎盟萨,沒想到半個(gè)月后凉翻,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,775評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡捻激,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年制轰,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片胞谭。...
    茶點(diǎn)故事閱讀 40,096評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡垃杖,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出丈屹,到底是詐尸還是另有隱情缩滨,我是刑警寧澤,帶...
    沈念sama閱讀 35,789評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站脉漏,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏袖牙。R本人自食惡果不足惜侧巨,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望鞭达。 院中可真熱鬧司忱,春花似錦、人聲如沸畴蹭。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)叨襟。三九已至繁扎,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間糊闽,已是汗流浹背梳玫。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留右犹,地道東北人提澎。 一個(gè)月前我還...
    沈念sama閱讀 48,308評(píng)論 3 372
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像念链,于是被迫代替她去往敵國(guó)和親盼忌。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容