摘要:中的事件不存在以上問題掛載的每個函數(shù)都可以控制在組件中,不會污染全局空間中沒有產(chǎn)生直接使用的,而是使用了事件委托方式處理,無論有多少個出現(xiàn),其實最后都只在樹上添加了一個事件處理函數(shù),掛在最頂層的節(jié)點上。
深入淺出React(一) 1、create-react-app工具使用
安裝create-react-app
npm install create-react-app -g
創(chuàng)建項目
creact-react-app demos cd demos npm start
分解應(yīng)用
package.json
"scripts": { "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test --env=jsdom", "eject": "react-scripts eject" }
npm start啟動開發(fā)環(huán)境,npm run build創(chuàng)建生產(chǎn)環(huán)境優(yōu)化代碼,npm test用于測試單元,npm run eject把潛藏在react-scripts中的一序列技術(shù)棧“彈射”到
應(yīng)用的頂端,此命令不可逆且會改變和增加一些文件。
數(shù)據(jù)驅(qū)動渲染
開發(fā)者不需要像jQuery一樣詳細(xì)的操作DOM著重于‘如何去做’,只需要著重于“我要顯示什么”,而不用操心“怎樣去做”;
react理念UI = reader(data)
用戶看到的界面(UI),是一個 純函數(shù)(render) 的執(zhí)行結(jié)果,只接受數(shù)據(jù)(data)作為參數(shù);
純函數(shù):沒有任何副作用,輸出完全依賴于輸入的函數(shù);
對于react開發(fā)者,重要的是區(qū)分哪些屬于data,哪些屬于render,要更新界面,要做的就是更新data;
react實踐的也是"響應(yīng)式編程"的思想。
3、Virtual DOM
每次render函數(shù)被調(diào)用,都要把整個組件重新渲染一遍會浪費,而react對此利用Virtual DOM,讓每次渲染都只從新渲染最少的DOM;
DOM樹:HTML是結(jié)構(gòu)化文本,而DOM是結(jié)構(gòu)化文本的抽象表達(dá)形式,瀏覽器在渲染HTML格式網(wǎng)頁時,會先將HTML文本解析以構(gòu)建DOM樹,然后根據(jù)DOM樹渲渲染出用戶看到界面,當(dāng)改變內(nèi)容時,就去改變DOM樹上的節(jié)點;
雖然DOM樹只是一些簡單的JavaScript語句,但DOM操作會引起瀏覽器對網(wǎng)頁的從新布局和繪制,所以Web前端開發(fā)優(yōu)化原則之一: 盡量較少DOM操作 ;
react開發(fā)會中jsx語句,將被Babel解析為創(chuàng)建React組件或HTML元素的語句,但React并不會通過其直接構(gòu)建或操作DOM樹,而是先構(gòu)建Virtual DOM;
DOM樹是對HTML的抽象,而Virtual DOM是對DOM樹的抽象;
Vritual DOM不觸及瀏覽器,只存在于JavaScript空間的樹形結(jié)構(gòu),每次自上而下的渲染React組件時,都會對比此次產(chǎn)生的Vritual DOM和上一次產(chǎn)生的,然后真正的DOM樹只需要操作有差別的部分。
4、JSX
JSX: 是JavaScript的語法擴(kuò)展,允許我們在JavaScript中編寫HTML一樣的代碼,最終會編譯成普通的JavaScript語句;
屬性使用
自定義屬性data-*;
class和for為JavaScript保留關(guān)鍵字,所以class和for屬性使用className和htmlFor;
JavaScript表達(dá)式使用
JSX允許在閉合標(biāo)簽中使用JavaScript表達(dá)式,但必須用{}包裹;
JavaScript表達(dá)式要求必須有 返回值 ,所以不能直接使用 if else 語句,但可以使用三元操作表達(dá)式和&&,||這樣的比較運算符來書寫;
如果確實需要使用 if else語句,可以寫在函數(shù)中,然后在{}中調(diào)用。
樣式
通過style屬性定義,單屬性值不能是字符串只能是對象,且屬性名需要使用駝峰命名法(font-size變?yōu)閒ontSize)。
注釋
標(biāo)簽內(nèi)注意需要寫在{}中。
數(shù)組
JSX中的數(shù)組會自動展開;
注意如果數(shù)組或迭代器中的每一項都是HTML標(biāo)簽或組件,那么它們必須要擁有唯一的key屬性,這樣有助于React的DIFF算法,實現(xiàn)最高效的DOM更新。
事件掛載
JSX中可以通過onClick(HTML原生為onclick)
HTML直接使用onclick缺點:
onclick添加的事件處理函數(shù)是在全局環(huán)境下執(zhí)行,污染全局環(huán)境,容易產(chǎn)生意想不到的后果;
給很多DOM元素添加onclick事件,可能會影響網(wǎng)頁的性能;
對于使用onclick的DOM元素,如果要動態(tài)的從DOM樹種刪除,需要把對應(yīng)的事件處理器注銷,否則可能造成內(nèi)存泄漏。
JSX中的onClick事件(不存在以上問題)
onClick掛載的每個函數(shù)都可以控制在組件中,不會污染全局空間;
JSX中onClick沒有產(chǎn)生直接使用onclick的HTML,而是使用了 事件委托 方式處理,無論有多少個onClick出現(xiàn),其實最后都只在DOM樹上添加了一個事件處理函數(shù),掛在最頂層的DOM節(jié)點上。
所有的點擊事件都被這個事件處理函數(shù)捕獲,然后根據(jù)具體組件分配給特定函數(shù),所以性能較高;
因為React控制了組件的生命周期,在unmount的時候能夠清除相關(guān)的所有事件處理函數(shù),內(nèi)存泄漏問題解決。
function Demo(){ const name = "jsx"; const arr = [3. React數(shù)據(jù)數(shù)組
數(shù)組會自動展開,注意添加key屬性
]; const func = () => { let result = "hello"; if (name){ result += name; } else { result += "world"; } return result; }; return ({/*注釋*/}) }hello {name || "world"}
hello {name && "world"}
{func()}
{arr}
React的prop
prop(property的簡寫)是從外部傳遞給組件的數(shù)據(jù),一個組件通過定義自己能夠接受的prop就定義了自己的對外公共接口;
每個React組件都是獨立存在的模塊,組件之外的一切都是外部世界,外部世界就是通過prop來和組件對話的。
給prop賦值
class Demo extends Component{ render(){ return() } }//給子組件 傳入caption和initValue信息,子組件需定義相關(guān)prop接口
讀取prop值
給this.prop賦值是React.Component構(gòu)造函數(shù)的工作之一;
如果一個組件需要定義自己的構(gòu)造函數(shù),一定要在構(gòu)造函數(shù)的第一行super調(diào)用父類也就是React.Component的構(gòu)造函數(shù);
如果沒有在構(gòu)造函數(shù)中調(diào)用super(props),那么組件實例被構(gòu)造之后,類實例的所有成員就無法通過this.props訪問到父組件傳遞過來的props值。
class Child extends Component{ constructor(props){ super(props); this.state = { //獲取外部傳入的prop,并用于state初始化 count: props.initValue || 0, caption: props.caption } } }
propTypes檢查
prop是組件的對外接口,所以一個組件該聲明自己的接口規(guī)范,規(guī)范組件支持哪些prop,每個prop該是什么樣的格式;
React通過propTypes來規(guī)范,因為propTypes已經(jīng)從React包中分離出來,所以新版React中無法使用React.PropTypes.*,需導(dǎo)入prop-types
即安裝:npm install prop-type --save導(dǎo)入import PropTypes from ("prop-types")
propTypes驗證器
JavaScript基本類型:
PropTypes.array
PropTypes.bool
PropTypes.func
PropTypes.number
PropTypes.object
PropTypes.string
可以被渲染為子節(jié)點的對象,包括數(shù)值、字符串ReactElement(指的是JSX中的閉合標(biāo)簽)或數(shù)組:
PropTypes.node
ReactElement
PropTypes.element
指定類的實例
PropTypes.instanceOf(Message)
只接受指定的值:
PropTypes.oneOf(["News","Photos"])
多個對象類型中的一個:
PropTypes.oneOfType([
PropTypes.string,
PropTypes.number,
PropTypes.instanceOf(Message)
])
指定類型組成的數(shù)組:
PropTypes.arrayOf(PropTypes.number)
指定類型的屬性構(gòu)成的對象:
PropTypes.objectOf(PropTypes.number)
符合指定格式的對象:
PropTypes.shape({
color: PropTypes.string,
fontSize: PropTypes.number
})
在任意類型上加上isRequired使其不為空:
PropTypes.func.isRequired
eg: Child.propTypes = { initValue: PropTypes.number, caption: PropTypes.string }
React的state
state代表組件的內(nèi)部狀態(tài),由于React組件不能修改傳入的prop,所以需要使用state記錄自身數(shù)據(jù)變化;
state初始化
constructor(props){ ... this.state = { count: props.initValue || 0 } }
注意:使用React.createClass方法創(chuàng)建出來的組件類,通過getInitialState方法獲取初始值,但這種方法已被廢棄。
讀取和更新state
讀取this.state
更新this.setState({})
注意:不要直接修改this.state的值,雖然能夠改變組件的內(nèi)部狀態(tài),但只是野蠻的修改了state,卻不會驅(qū)動組件從新渲染,所以變化不會反應(yīng)到界面
而,this.setState()所做的事是先改變this.state的值,然后驅(qū)動組件更新
prop和state對比
prop用于定義外部接口,state用于記錄內(nèi)部狀態(tài);
prop的賦值在外部世界使用組件時,state的賦值在組件內(nèi)部;
組件不應(yīng)該改變prop的值,而state的存在就是為了讓組件來改變。
React的context
使用prop給內(nèi)部子組件傳遞數(shù)據(jù)時需要一層一層的傳遞,即使中間有組件不需要使用,這樣比較麻煩;
使用context可以實現(xiàn)跨級傳遞。
context使用步驟
父組件通過getChildContext()方法將需要傳入的信息放進(jìn)context,并聲明childContextTypes(如果不聲明無法再組件中使用getChildContext());
要使用的子組件中通過聲明contextTypes(需要和父組件一致)就可以通過組件實例的context屬性訪問接收到的數(shù)據(jù);
無狀態(tài)的組件可以在函數(shù)參數(shù)中獲取context;而又狀態(tài)的組件可以通過this.context和生命周期函數(shù)獲取context。
eg:
父組件
class Parent extends React.Component{ getChildContext(){ return {color: "red"} } render(){ return() } } Parents.childContextTypes = { color: PropTypes.string.isRequired }
(有狀態(tài))子組件:
class Child extends React.Component{ render(){ return() } } Child.contextTypes = { color: PropTypes.string.isRequired }有狀態(tài)的組件可以通過this.context獲取
(無狀態(tài))孫子組件:
function Grandchild(context){ return(無狀態(tài)組件可以直接在函數(shù)的參數(shù)中獲取
) } Grandchild.contextTypes = { color:PropTypes.string.isRequired }
不積跬步,何以行千里
持續(xù)加載中.....
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/92989.html
摘要:中的元素組件實例和節(jié)點,是中關(guān)系密切的個概念,也是很容易讓初學(xué)者迷惑的個概念。組件和元素關(guān)系密切,組件最核心的作用是返回元素。只有組件實例化后,每一個組件實例才有了自己的和,才持有對它的節(jié)點和子組件實例的引用。 React 深入系列,深入講解了React中的重點概念、特性和模式等,旨在幫助大家加深對React的理解,以及在項目中更加靈活地使用React。 React 中的元素、組件、實...
摘要:中的元素組件實例和節(jié)點,是中關(guān)系密切的個概念,也是很容易讓初學(xué)者迷惑的個概念。組件和元素關(guān)系密切,組件最核心的作用是返回元素。只有組件實例化后,每一個組件實例才有了自己的和,才持有對它的節(jié)點和子組件實例的引用。 文:徐超,《React進(jìn)階之路》作者授權(quán)發(fā)布,轉(zhuǎn)載請注明作者及出處 React 深入系列,深入講解了React中的重點概念、特性和模式等,旨在幫助大家加深對React的理解...
摘要:前言以深入學(xué)習(xí)技術(shù)棧為線索,記錄下學(xué)習(xí)的重要知識內(nèi)容。要傳入時,必須使用屬性表達(dá)式。如果要使用自定義屬性,要使用前綴這與標(biāo)準(zhǔn)是一致的。 前言 以《深入學(xué)習(xí)react技術(shù)棧》為線索,記錄下學(xué)習(xí)React的重要知識內(nèi)容。本系列文章沒有涵蓋全部的react知識內(nèi)容,只是記錄下了學(xué)習(xí)之路上的重要知識點,一方面是自己的總結(jié),同時拿出來和在學(xué)習(xí)react的人們一塊分享,共同進(jìn)步。 正文 一:rea...
摘要:本篇是深入系列的最后一篇,將介紹開發(fā)應(yīng)用時,經(jīng)常用到的模式,這些模式并非都有官方名稱,所以有些模式的命名并不一定準(zhǔn)確,請讀者主要關(guān)注模式的內(nèi)容。 React 深入系列,深入講解了React中的重點概念、特性和模式等,旨在幫助大家加深對React的理解,以及在項目中更加靈活地使用React。 本篇是React深入系列的最后一篇,將介紹開發(fā)React應(yīng)用時,經(jīng)常用到的模式,這些模式并非都有...
摘要:當(dāng)真正執(zhí)行狀態(tài)修改時,依賴的并不能保證是最新的,因為會把多次的修改合并成一次,這時,還是等于這幾次修改發(fā)生前的。下篇預(yù)告深入系列組件的生命周期新書推薦進(jìn)階之路作者徐超畢業(yè)于浙江大學(xué),碩士,資深前端工程師,長期就職于能源物聯(lián)網(wǎng)公司遠(yuǎn)景智能。 文:徐超,《React進(jìn)階之路》作者授權(quán)發(fā)布,轉(zhuǎn)載請注明作者及出處 React 深入系列3:Props 和 State React 深入系列,深...
閱讀 3072·2021-11-25 09:43
閱讀 2251·2021-09-07 10:28
閱讀 3543·2021-08-11 11:14
閱讀 2777·2019-08-30 13:49
閱讀 3544·2019-08-29 18:41
閱讀 1162·2019-08-29 11:26
閱讀 1976·2019-08-26 13:23
閱讀 3372·2019-08-26 10:43