摘要:語法是一種語法的拓展語言,在中官方也推薦使用描述用戶界面,使用起來會比較快捷而且易讀不是一門新的語言,可以理解為是一種語法糖,作用就是能夠讓我們更加直觀的在中創(chuàng)建標簽,最終還是會被編譯為語法,例如我們看一段代碼上面的語法最終會被編譯為語法,
Reatc JSX語法
jsx是一種JavaScript語法的拓展語言,在React中官方也推薦使用jsx描述用戶界面,使用起來會比較快捷而且易讀
jsx不是一門新的語言,可以理解為是一種語法糖,作用就是能夠讓我們更加直觀的在js中創(chuàng)建html標簽,jsx最終還是會被編譯為JavaScript語法,例如我們看一段jsx代碼:
/*jsx*/ ReactDOM.render(, document.querySelector("#root") )hello world
上面的jsx語法最終會被編譯為JavaScript語法,中間就是通過一個React.createElement的方法來轉化,轉換后就是下面這段代碼
ReactDOM.render( React.createElement( "div", {className:"wrap"}, "", React.createElement( "h1", null, "hello world" ) ), document.querySelector("#root") )
比較兩段代碼就可以看出來使用js語法來寫的話實在不夠簡練,所以我們通常還是使用jsx的語法
在使用jsx的時候,需要注意幾個點
在使用jsx的地方,要注意我們的代碼不能被JavaScript引擎直接解析,所以要在為script標簽設置特殊的type屬性, 阻止JavaScript引擎的解析
在jsx中只能有一個根節(jié)點,如果存在多個根節(jié)點會報錯,jsx同時也可以進行標簽的嵌套
ReactDOM.render(/*根節(jié)點*/, document.querySelector("#root") )hello world
在jsx中,我們雖然寫的時候看起來比較像是直接寫html,但實際上還是JavaScript,所以需要使用JavaScript的語法,例如我們在為標簽添加class屬性時,不能寫class,而是要使用JavaScript語法的className,這樣才能被正確的解析
ReactDOM.render(, document.querySelector("#root") )
同樣的其他一些屬性也需要轉化為駝峰寫法,如tabindex?則對應著?tabIndex
在jsx中使用單標簽,需要在結尾處使用/>,否則不能夠被正確的解析
ReactDOM.render(, document.querySelector("#root") )
在jsx中可以任意的使用JavaScript的表達式,但是需要將表達式放置在{}中
const obj = { name: "tom", age: (age) => { return age; } } ReactDOM.render(, document.querySelector("#root") ) /*編譯結果*/ //我是tom,年齡是18,2+2是8,0>1的結果是false我是{obj.name},年齡是{obj.age(18)},2+2是{3 + 5},0>1的結果是{0 > 1 ? "true" : "false"}
由于jsx本身就是JavaScript,所以我們也可以通過條件判斷來決定控制模板的內容
const obj = { name: "tom", age: (age) => { return age; } }; function judgment(user) { let component; component = user ?控制樣式:我是{obj.name},年齡是{obj.age(18)},2+2是{3 + 5},0>1的結果是{0 > 1 ? "true" : "false"}
出現錯誤了哦return component; } ReactDOM.render( judgment(true), document.querySelector("#root") )
React中并沒有提供其他框架中的例如ng-show、v-if等命令,這些都是需要我們自己手動去寫的
控制元素的顯示/隱藏
class Control extends React.Component { constructor(...args) { super(...args); this.state = { flag: "block" } } fn() { this.setState({ flag: this.state.flag == "block" ? "none" : "block" }) } render() { return} } ReactDOM.render(, document.querySelector("#root") )
控制class樣式
class Control extends React.Component { constructor(...args) { super(...args); this.state = { flag: true } } fn() { this.setState({ flag:!this.state.flag }) } render() { return} } ReactDOM.render(是否渲染
, document.querySelector("#root") )
在實際開發(fā)中上面的方法都不是很直觀,推薦使用classnames庫
class Control extends React.Component { constructor(...args) { super(...args); this.state = { flag: false } } fn() { this.setState({ flag:!this.state.flag }) } render() { return組件} } ReactDOM.render(是否渲染
{ this.state.flag ? : null }, document.querySelector("#root") )
組件這個概念現在也是非常流行了,如果之前沒有使用過其他框架的話可以用一個相對比較通俗的例子來理解組件的概念,Moto之前推出過好幾款模塊化的手機,該手機包括屏幕,處理器,內存,電池,攝像頭等,都支持自由更換拼裝,然后組裝成一個完整的手機
, document.querySelector("#root") )
注意,使用組件時,組件名稱一定要是大寫字母開頭的,否則的話會被認為是普通的html文本進行解析,同時也需要注意的是組件內只允許有一個根元素
組件的嵌套在React中,組件之間是可以嵌套使用的
class Hello extends React.Component { render() { return容器類組件hello} } class Wrold extends React.Component { render() { return} } ReactDOM.render(world
, document.querySelector("#root") )
這個概念類似于Vue中的插槽,如果沒有Vue知識的可以將這個理解為在在使用某個組件時我們在該組件內插入一些DOM元素,而且要保證這些DOM元素能夠被正確渲染
class FancyBorder extends React.Component { render() { return ({this.props.children}) } } ReactDOM.render(, document.querySelector("#root") ) Lorem ipsum dolor sit amet.
Lorem ipsum dolor.
這里就借用一下Vue的概念,我們將組件中設定了{this.props.children} 的部分稱為插槽
在需要插入來自調用者的DOM的部分寫入{props.children},之后調用者插入的代碼就會在我們寫入了{props.children}的位置上被展示
我們此時可以打印一下props.children,可以發(fā)現得到的是一個數組的結果
, document.querySelector("#root") ) 組件之間的通信
class Child extends React.Component { render() { returnhello {this.props.name}} } class Parent extends React.Component { render() { return} } ReactDOM.render(, document.querySelector("#root") )
props方法時官方提供的接口,我們在使用組件時,在引用子組件處,將要傳遞的內容以設置屬性的方式添加到子組件,在子組件中通過this.props[父組件設置的屬性名]的格式就可以獲取到父組件傳遞的信息,通過props可以傳遞字符串、數字、對象、數組、函數 ,子組件在可以通過this.props來查看當前所有接收到的值
class Child extends React.Component { click(e) { console.log(this.props.data,"child"); e.stopPropagation(); } render() { returnhello {this.props.data.name}} } class Parent extends React.Component { constructor() { super(); this.state = { obj: { name: "tom", age: 18 } } } click() { console.log(this,"parent") } render() { return} } ReactDOM.render(, document.querySelector("#root") )
class Child extends React.Component { render() { return } } class Parent extends React.Component { click(e) { console.log(this) e.stopPropagation() } render() { return} } ReactDOM.render(, document.querySelector("#root") )
傳遞事件的時候可以通過bind改變我們最初事件的this的指向,這里我們看打印的結果,this的指向在child中指向的是child組件
狀態(tài)提升這個概念其實可以理解為我們在其他框架中使用的姜子組件的信息傳遞給父組件的一個過程,但是在react中并沒有提供直接的方法,需要我們自己進行處理,實現的代碼如下:
class Child extends React.Component { click(i,e) { i++; this.props.P_click(i); e.stopPropagation(); } render() { return} } class Parent extends React.Component { constructor() { super(); this.state = { index: 1 } this.P_Click = this.P_Click.bind(this) } change(data) { this.setState({ index: data }); } render() { return{this.state.index}} } ReactDOM.render(, document.querySelector("#root") )
我們首先來說一下大概的思路
在父組件中設置一個方法change,在該方法中設置改變我們指定的變量值的處理
change(data) { this.setState({ index: data }); }
將該方法傳遞給子組件,同時也將我們要要改變的父組件的值傳遞給子組件
在子組件操作時,例如點擊時,調用我們在父組件中傳入的change方法,并改變由父組件發(fā)送過來的數據(index),回傳給change方法
click(i,e) { i++; this.props.P_click(i) e.stopPropagation(); }
change方法被調用,通過this.setState響應的改變了父組件中index值
可以看出來確實很麻煩,由于沒有像vue那樣提供$emit方法,所以需要我們自己迂回寫一系列操作,包括如果我們想要在同級的組件之間傳遞數據,我們需要 子組件數據 => 父組件 => 子組件兄弟組件
推薦使用Redux來進行組件之間的數據傳遞
響應式的更新數據 生命周期, document.querySelector("#root") )
在執(zhí)行上訴代碼之后,我們會看到一行報錯
react.js:369 Warning: Each child in an array or iterator should have a unique "key" prop.Check the render method of Lists.
這是React提示需要在為我們通過遍歷渲染的li添加key值,采用如下操作
React是不會去渲染之前已經存在的元素,這也是React的高效性的原因之一,key值可以幫助React識別那些元素發(fā)生了變化,那些沒有變化,從而使React在渲染時保留那些之前已經被渲染的元素
還是上面的代碼,我們打開控制臺,在為第一個li添加一個臨時的color,然后點擊添加按鈕,可以發(fā)現這個li的樣式依然被保持了,說明React沒用重新渲染該元素
, document.querySelector("#root") )
然后我們嘗試在輸入框中輸入文字會發(fā)現不論輸入什么內容,輸入框中會依然保持是react,這是因為在我們創(chuàng)建input的時候,value就已經被react劫持了
react也會特別貼心的進行提示
Failed prop type: You provided a value prop to a form field without an onChange handler. This will render a read-only field. If the field should be mutable use defaultValue. Otherwise, set either onChange or readOnly. in input
根據提示,我們可以發(fā)現我們需要設置為如下的格式
ReactDOM.render( , document.querySelector("#root") )
這個時候我們就可以正常的修改表單數據了,同樣的會被react劫持的還有一個屬性,就是checked,在使用時同樣需要轉換為React提供的defaultChecked
react中是沒有雙向綁定這個概念的,實際的react其實可以理解為是一個單向的數據綁定,所有的頂層具有的state做為數據流通過props向下傳遞給子組件,然后在數據改變的時候重新調用render,重而重新渲染頁面
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/97299.html
摘要:希望大家在這浮夸的前端圈里,保持冷靜,堅持每天花分鐘來學習與思考。 今天的React題沒有太多的故事…… 半個月前出了248個Vue的知識點,受到很多朋友的關注,都強烈要求再出多些React相前的面試題,受到大家的邀請,我又找了20多個React的使用者,他們給出了328道React的面試題,由我整理好發(fā)給大家,同時發(fā)布在了前端面試每日3+1的React專題,希望對大家有所幫助,同時大...
摘要:中的元素組件實例和節(jié)點,是中關系密切的個概念,也是很容易讓初學者迷惑的個概念。組件和元素關系密切,組件最核心的作用是返回元素。只有組件實例化后,每一個組件實例才有了自己的和,才持有對它的節(jié)點和子組件實例的引用。 React 深入系列,深入講解了React中的重點概念、特性和模式等,旨在幫助大家加深對React的理解,以及在項目中更加靈活地使用React。 React 中的元素、組件、實...
摘要:中的元素組件實例和節(jié)點,是中關系密切的個概念,也是很容易讓初學者迷惑的個概念。組件和元素關系密切,組件最核心的作用是返回元素。只有組件實例化后,每一個組件實例才有了自己的和,才持有對它的節(jié)點和子組件實例的引用。 文:徐超,《React進階之路》作者授權發(fā)布,轉載請注明作者及出處 React 深入系列,深入講解了React中的重點概念、特性和模式等,旨在幫助大家加深對React的理解...
摘要:在前端開發(fā)過程中,源碼解讀是必不可少的一個環(huán)節(jié),我們直接進入主題,注意當前版本號。注意包文件僅僅是的必要的功能性的定義,它必須要結合一起使用下是,原生環(huán)境下是。 在前端開發(fā)過程中,源碼解讀是必不可少的一個環(huán)節(jié),我們直接進入主題,注意當前 React 版本號 16.8.6。 注意:react 包文件僅僅是 React components 的必要的、功能性的定義,它必須要結合 React...
摘要:內部機制探秘和文末附彩蛋和源碼這篇文章比較偏基礎,但是對入門內部機制和實現原理卻至關重要。當然也需要明白一些淺顯的內部工作機制。當改變出現時,相比于真實更新虛擬的性能優(yōu)勢非常明顯。直到最終,會得到完整的表述樹的對象。 React 內部機制探秘 - React Component 和 Element(文末附彩蛋demo和源碼) 這篇文章比較偏基礎,但是對入門 React 內部機制和實現原...
摘要:本文翻譯自原作者如果有任何版權問題,請聯(lián)系當你在組件中調用時,你覺得會發(fā)生什么當然,會用這條狀態(tài)重新渲染組件并且更新匹配到的,然后返回元素。如果你之前使用過一些渲染器比如說,你可能知道在頁面中使用超過一個渲染器是沒什么問題的。 本文翻譯自:How Does setState Know What to Do?原作者:Dan Abramov 如果有任何版權問題,請聯(lián)系shuirong199...
閱讀 2973·2021-10-27 14:16
閱讀 695·2021-10-13 09:39
閱讀 3669·2021-09-29 09:46
閱讀 2090·2019-08-30 15:54
閱讀 2597·2019-08-30 15:52
閱讀 2994·2019-08-30 15:44
閱讀 1103·2019-08-30 15:44
閱讀 497·2019-08-30 10:51