摘要:在構(gòu)造函數(shù)里面初始化的數(shù)據(jù),把數(shù)據(jù)放在頁(yè)面上,點(diǎn)擊時(shí)候調(diào)用方法改變中的數(shù)據(jù)。是中父組件向子組件通信的方式,下面是一個(gè)簡(jiǎn)單的例子使用組件我是顯示的數(shù)據(jù)我們定義組件時(shí)候在構(gòu)造函數(shù)中可以接收到參數(shù),并且要使用傳到的構(gòu)造方法中。
React的學(xué)習(xí)之路還要繼續(xù)走下去,最近一邊在做未完成的項(xiàng)目一邊學(xué)習(xí)React,項(xiàng)目是vue寫(xiě)的,后面還需要有一個(gè)后臺(tái)管理系統(tǒng)計(jì)劃使用react完成,寒假說(shuō)長(zhǎng)也不長(zhǎng),要抓緊時(shí)間了。
有人愛(ài)有人恨的語(yǔ)法糖--jsx jsx簡(jiǎn)介很多人不喜歡React,很大程度上是因?yàn)椴幌矚gjsx,那么jsx到底是什么呢?首先還是不要忘了React的基本哲學(xué)--一切都是js,包括文檔結(jié)構(gòu)。所以曾經(jīng)每天都會(huì)見(jiàn)到的html在react的世界里全都不存在,react通過(guò)一系列叫做react元素的對(duì)象來(lái)構(gòu)建虛擬DOM結(jié)構(gòu),最原始的創(chuàng)建react元素的方式是這樣的:
const root = React.createElement("div", { className: "main" }, "我是一個(gè)div");
最終它將返回一個(gè)大概這樣子的對(duì)象(有所簡(jiǎn)化過(guò),不代表在 React 源碼中是這樣):
const root = { type: "div", props: { className: "main", children: "我是一個(gè)div" } };
這樣一個(gè)個(gè)創(chuàng)建節(jié)點(diǎn)其實(shí)是很麻煩的,想想看,如果每個(gè)整個(gè)虛擬DOM的內(nèi)容都要通過(guò)React.createElement來(lái)創(chuàng)建,代碼量會(huì)很多,而且我們根本無(wú)法直觀地看出樹(shù)形結(jié)構(gòu),無(wú)論開(kāi)發(fā)還是維護(hù)性都及其不友好。為了解決這一問(wèn)題,一種新型的,類(lèi)似xml結(jié)構(gòu)的語(yǔ)法擴(kuò)展就誕生了,就是jsx。
上面的代碼結(jié)構(gòu)改成jsx的書(shū)寫(xiě)方式就是這樣的:
const root =(我是一個(gè)div);
這個(gè)結(jié)構(gòu)就很熟悉了,不過(guò)要記住,他不是html模板,它就是js,最終在執(zhí)行之前會(huì)被完全轉(zhuǎn)義成為純js代碼,所以使用jsx是不存在任何性能問(wèn)題的。
jsx語(yǔ)法jsx的標(biāo)準(zhǔn)語(yǔ)法結(jié)構(gòu)和xml完全類(lèi)似,特別的,jsx中的html屬性要寫(xiě)成小駝峰命名的形式,比如onclick就要寫(xiě)成onClick。另一點(diǎn)需要注意的問(wèn)題就是,由于class是js中的保留字,所以要用className來(lái)代替。
jsx使用jsx時(shí)候要時(shí)刻記住它是js表達(dá)式,所以它可以像普通的js表達(dá)式一樣,賦值傳參返回都可以。而在jsx內(nèi)部如果想使用表達(dá)式,就需要放在{}里面。這就是jsx語(yǔ)法,非常簡(jiǎn)單,也不需要記憶特殊的指令,一切都可以和處理js一樣來(lái)處理,下面來(lái)看一個(gè)小例子:
const item = this.newsList.map((news, index) => (
這是一個(gè)在react開(kāi)發(fā)中特別常見(jiàn)的使用場(chǎng)景,我們得到了一個(gè)數(shù)組的數(shù)據(jù),需要以列表的形式渲染出來(lái)。在react中不需要使用任何迭代判斷的相關(guān)指令語(yǔ)法,只要會(huì)寫(xiě)js的都能看懂上面的邏輯:通過(guò)數(shù)組的map方法迭代數(shù)組的內(nèi)容,在回調(diào)函數(shù)中處理數(shù)據(jù),渲染成想要的樣式,就得到了一條一條列表項(xiàng),插到列表里面就完成數(shù)據(jù)渲染了。我們可以發(fā)現(xiàn)在不論是迭代方法還是三元表達(dá)式等等,只要是js語(yǔ)法就可以隨意地寫(xiě)到里面,自由度非常高。
可復(fù)用的基本單位--組件 為什么要使用組件了解了jsx,下一個(gè)重要概念就是組件了。組件不是react特有的,組件化開(kāi)發(fā)有很多好處,組件符合高內(nèi)聚低耦合的要求,每一個(gè)組件是封裝了視圖和邏輯的一個(gè)相對(duì)獨(dú)立的個(gè)體,而整個(gè)頁(yè)面是由多個(gè)組件構(gòu)成的,每個(gè)組件可以多次復(fù)用。
組件可以理解為類(lèi)似于函數(shù)調(diào)用一樣,定義好的組件是一個(gè)抽象的視圖,而我們通過(guò)傳入相關(guān)的“參數(shù)”來(lái)使它展示出我們想要的樣子,組件就是我們復(fù)用各種獨(dú)立部件的基本單位。
React中的組件定義一個(gè)組件最簡(jiǎn)單的方式是使用JavaScript函數(shù):
function Welcome(props) { returnHello, {props.name}
; }
這是一個(gè)最簡(jiǎn)單的函數(shù)定義組件,整個(gè)函數(shù)調(diào)用結(jié)果實(shí)際上就是返回一個(gè)標(biāo)簽,不過(guò)特別的是,標(biāo)簽的內(nèi)容不是確定的,它是由我們傳入的參數(shù)來(lái)決定的。這就是組件開(kāi)發(fā),在React中,最常用的不是函數(shù)聲明組件,而是向下面一樣:
class Welcome extends React.Component { render() { returnHello, {this.props.name}
; } }
此處使用了ES6的類(lèi)和繼承,創(chuàng)建了一個(gè)繼承自Component的類(lèi)。這個(gè)組件和上一個(gè)組件效果是完全相同的,下面來(lái)重點(diǎn)分析React組件中幾個(gè)重要的概念。
核心數(shù)據(jù)狀態(tài)--state什么是state?狀態(tài),在react組件中,state是指一個(gè)組件UI呈現(xiàn)的最小狀態(tài)集。在react中,視圖層的更新是通過(guò)處理狀態(tài)的變化來(lái)實(shí)現(xiàn)的,而state就是對(duì)這一系列狀態(tài)的定義。react的數(shù)據(jù)是單向流動(dòng)的,數(shù)據(jù)只能從模型層流向視圖層,對(duì)應(yīng)到具體的實(shí)現(xiàn),我們對(duì)state所做的一系列處理會(huì)自動(dòng)的反映到視圖上,我們想要更新視圖,只更新?tīng)顟B(tài)即可。說(shuō)的可能比較抽象,看一個(gè)具體例子:
class ClickMe extends React.Component { constructor(props) { super(props); this.state = { count: 0 }; } clicked() { this.setState({ count: this.state.count + 1 }); } render() { return (this.clicked()}> 點(diǎn)我{this.state.count}次); } }
這個(gè)組件的效果就是點(diǎn)擊文字,會(huì)顯示你的點(diǎn)擊次數(shù),效果很簡(jiǎn)單就不截圖了,關(guān)于組件生命周期和點(diǎn)擊事件綁定后面再看,這里重點(diǎn)來(lái)看state的變化。在構(gòu)造函數(shù)里面初始化state的數(shù)據(jù),把state數(shù)據(jù)放在頁(yè)面上,點(diǎn)擊時(shí)候調(diào)用setState方法改變state中的數(shù)據(jù)。
關(guān)于state有幾點(diǎn)需要注意:
state不能直接修改,直接修改state的值是不會(huì)更新視圖的,正確的更新方式是使用setState來(lái)改變state的值。
不是所有的變量都要放到state中,state里面的變量一方面是要來(lái)描述組件自身狀態(tài),不需要反映到視圖上的內(nèi)容不是state。
state是最小狀態(tài)集,取自父組件的狀態(tài)信息不是自身狀態(tài),不能放在state中。從外部傳入的東西要放在props中。
外部傳遞屬性--propsprops是組件的另一個(gè)非常重要的概念,props指的是從外部傳入的屬性。props是React中父組件向子組件通信的方式,下面是一個(gè)簡(jiǎn)單的例子:
class Child extends React.Component { constructor(props) { super(props); } render() { return ({this.props.data}); } }
使用組件
我們定義組件時(shí)候在構(gòu)造函數(shù)中可以接收到props參數(shù),并且要使用super傳到Component的構(gòu)造方法中。在整個(gè)組件的類(lèi)中就可以使用成員變量props了。而props的內(nèi)容,是父元素在調(diào)用子元素時(shí)候以屬性的形式傳入的。整個(gè)props控制的就是從父元素到子元素的事件流,這樣我們?cè)谑褂媒M件的時(shí)候就可以像函數(shù)調(diào)用一樣使用組件,像傳入?yún)?shù)一樣傳入props。
使用props時(shí)候要注意一點(diǎn),props傳遞數(shù)據(jù)是單向的,數(shù)據(jù)只能從父組件傳遞到子組件,需要其它方向的數(shù)據(jù)傳遞就需要使用其他方式了。
組件從創(chuàng)建到銷(xiāo)毀--生命周期生命周期這個(gè)概念在很多開(kāi)發(fā)中都會(huì)接觸,react也是如此,一個(gè)react組件從創(chuàng)建運(yùn)行到銷(xiāo)毀需要經(jīng)歷很多階段,系統(tǒng)也為我們提供了對(duì)應(yīng)階段的hook方法(hook方法翻譯為鉤子方法,指的是當(dāng)組件運(yùn)行到對(duì)應(yīng)的階段時(shí)候就會(huì)自動(dòng)執(zhí)行寫(xiě)在這些方法里面的邏輯),我從網(wǎng)上找到了一副描述比較清晰的圖片(侵刪):
下面來(lái)逐一介紹這些生命周期方法以及它們說(shuō)發(fā)揮的作用
getDefaultProps和getInitialState,如果使用ES6的類(lèi)繼承方式定義組件是看不到這兩個(gè)方法的,它們的任務(wù)是組件加載前先獲取默認(rèn)props和初始化state,在ES6的語(yǔ)法中我們可以在constructor中對(duì)其進(jìn)行定義,注意constructor第一句必須要使用super(props),否則會(huì)報(bào)錯(cuò)。
componentWillMount,在組件渲染之前調(diào)用,整個(gè)生命周期只會(huì)調(diào)用一次,子組件的該方法會(huì)在父組件調(diào)用之后被調(diào)用,如果在該方法內(nèi)設(shè)置狀態(tài),react會(huì)在狀態(tài)設(shè)置好之后才執(zhí)行渲染,常用在該方法里發(fā)送網(wǎng)絡(luò)請(qǐng)求獲取數(shù)據(jù)。
render(),組件渲染方法,此方法返回組件最終被渲染的狀態(tài),它的作用就是渲染組件,此階段不能修改state。從圖上可以看出,除了首次渲染要調(diào)用,此方法在組件發(fā)生更新時(shí)候也會(huì)被調(diào)用,它是組件最核心的方法。
componentDidMount,在逐漸被渲染之后被調(diào)用,僅調(diào)用一次,子組件的此方法會(huì)在父組件的此方法之前調(diào)用,此方法結(jié)束后組件進(jìn)入運(yùn)行狀態(tài)。
componentWillReceiveProps(nextProps),組件運(yùn)行階段,當(dāng)組件接收到新的props時(shí)被調(diào)用,這個(gè)函數(shù)接收一個(gè)object參數(shù)(新的props),父組件發(fā)生render的時(shí)候子組件就會(huì)調(diào)用,組件首次渲染不會(huì)觸發(fā)。
shouldComponentUpdate(nextProps, nextState),組件運(yùn)行階段,接收到新的state或props時(shí)被調(diào)用,此方法默認(rèn)返回true,可以通過(guò)控制該方法返回false來(lái)阻止組件重新渲染。
componentWillUpdate,組件運(yùn)行階段,當(dāng)準(zhǔn)備重新渲染組件前調(diào)用,做一些渲染前準(zhǔn)備工作,組件首次渲染不會(huì)觸發(fā)。
componentDidUpdate,組件運(yùn)行狀態(tài),組件重新渲染之后調(diào)用,組件首次渲染不會(huì)觸發(fā)。
componentWillUnmount,在組件被卸載前調(diào)用,做一些結(jié)束前的清理工作。
以上是react生命周期的相關(guān)內(nèi)容,到此,react組件的基本概念就介紹的差不多了。
行為與交互--事件綁定在react中綁定事件需要注意一個(gè)問(wèn)題,如果是使用ES6的class方式定義的組件中事件處理函數(shù)的this默認(rèn)是不會(huì)綁定的,我們需要手動(dòng)綁定this指向。來(lái)看下面一個(gè)錯(cuò)誤的例子:
class EventTest extends React.Component { clicked() { console.log("clicked"); } render() { return (點(diǎn)我); } }
點(diǎn)擊點(diǎn)我,確實(shí)能夠正常打印出clicked,看起來(lái)好像沒(méi)有問(wèn)題,但是,如果試著打印一下this,就會(huì)發(fā)現(xiàn)結(jié)果是undefined。
這樣寫(xiě)this沒(méi)辦法綁定,自然也就沒(méi)辦法使用各種成員變量和方法,也不能調(diào)用內(nèi)置方法了,顯然不是我們預(yù)期的,所以我們需要手動(dòng)來(lái)綁定this指向,方法也很簡(jiǎn)單:
class EventTest extends React.Component { clicked() { console.log("clicked"); } render() { return (點(diǎn)我); } }
只要增加bind(this)就能實(shí)現(xiàn)預(yù)期效果了,這也是一種常用的綁定this方式。除此之外還可以采用箭頭函數(shù)來(lái)自動(dòng)綁定this,下面的做法也是完全可以的:
class EventTest extends React.Component { clicked() { console.log("clicked"); } render() { return (this.clicked()}> 點(diǎn)我); } }
把clicked作為箭頭函數(shù)返回的函數(shù)來(lái)使用,利用箭頭函數(shù)內(nèi)部自動(dòng)綁定this的特性也可以實(shí)現(xiàn)this綁定。另外,還有一種寫(xiě)法:
class EventTest extends React.Component { clicked = () => { console.log("clicked"); } render() { return (點(diǎn)我); } }
這種方法是新的ES標(biāo)準(zhǔn)中的實(shí)驗(yàn)性語(yǔ)法,由于有babel轉(zhuǎn)譯也是可以使用的,官網(wǎng)上面也提到了這種寫(xiě)法,不過(guò)由于新的標(biāo)準(zhǔn)還未成熟,所以用的人也不多。
了解了這些,react算是入了門(mén)了,接下來(lái)深入學(xué)習(xí)的路還長(zhǎng),虛擬DOM的原理,diff算法,css-in-js,工程化下的react項(xiàng)目結(jié)構(gòu),react-router,redux,還有以后要學(xué)習(xí)的react native,后面隨著學(xué)習(xí)慢慢總結(jié)。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/92550.html
摘要:更多資源請(qǐng)文章轉(zhuǎn)自月份前端資源分享視頻前端技術(shù)論壇融合不可錯(cuò)過(guò)的迷你庫(kù)測(cè)試框架實(shí)例教程為你詳細(xì)解讀請(qǐng)求頭的具體含意解析的庫(kù)如果要用前端框架,開(kāi)發(fā)流程是怎樣的與有什么區(qū)別正確使用的方法是什么流程圖插件小如何讓元素只能輸入純文本前端技術(shù)中 更多資源請(qǐng)Star:https://github.com/maidishike... 文章轉(zhuǎn)自:https://github.com/jsfront...
摘要:我的入門(mén)到放棄之路最近看到很多相關(guān)的問(wèn)題跟討論,越來(lái)越多的小伙伴喜歡這個(gè)框架了,同時(shí)也在看到了有些入門(mén)的小伙伴遇到了各種各樣的問(wèn)題,本人也是框架使用都一枚,公司是騰訊阿里平安三巨頭合資的一家公司,分別上海深圳杭州北京廣州等多個(gè)分部,前端人員 showImg(https://segmentfault.com/img/bVbhonB?w=1278&h=722); 我的react入門(mén)到放棄之...
摘要:一些知識(shí)點(diǎn)有哪些方法方法前端從入門(mén)菜鳥(niǎo)到實(shí)踐老司機(jī)所需要的資料與指南合集前端掘金前端從入門(mén)菜鳥(niǎo)到實(shí)踐老司機(jī)所需要的資料與指南合集歸屬于筆者的前端入門(mén)與最佳實(shí)踐。 工欲善其事必先利其器-前端實(shí)習(xí)簡(jiǎn)歷篇 - 掘金 有幸認(rèn)識(shí)很多在大廠工作的學(xué)長(zhǎng),在春招正式開(kāi)始前為我提供很多內(nèi)部推薦的機(jī)會(huì),非常感謝他們對(duì)我的幫助?,F(xiàn)在就要去北京了,對(duì)第一份正式的實(shí)習(xí)工作也充滿(mǎn)期待,也希望把自己遇到的一些問(wèn)題和...
摘要:前端日?qǐng)?bào)精選騰訊前端團(tuán)隊(duì)社區(qū)源碼分析入門(mén)指南一些關(guān)于使用的心得基本類(lèi)型與引用類(lèi)型知多少掘金中文第期框架選型周刊第期入門(mén)系列模塊車(chē)棧重構(gòu)基于的網(wǎng)絡(luò)請(qǐng)求庫(kù)某熊的全棧之路的那些奇技淫巧的平凡之路模仿寫(xiě)個(gè)數(shù)組監(jiān)聽(tīng)掘 2017-07-01 前端日?qǐng)?bào) 精選 Why you shouldn`t use Preact, Fast-React, etc. to replace React today -...
閱讀 1052·2021-10-11 10:59
閱讀 3605·2021-09-26 09:55
閱讀 897·2019-08-30 15:55
閱讀 2653·2019-08-30 15:44
閱讀 438·2019-08-30 14:06
閱讀 685·2019-08-30 11:26
閱讀 3342·2019-08-30 10:49
閱讀 2481·2019-08-29 12:53