一、React JSX
1. JSX簡(jiǎn)介
JSX就是Javascript和XML結(jié)合的一種格式凹蜈。React發(fā)明了JSX,利用HTML語(yǔ)法來(lái)創(chuàng)建虛擬DOM仰坦。當(dāng)遇到<,JSX就當(dāng)HTML解析计雌,遇到{就當(dāng)JavaScript解析。
如下(JS寫(xiě)法)
var child1 = React.createElement('li', null, 'First Text Content');
var child2 = React.createElement('li', null, 'Second Text Content');
var root = React.createElement('ul', { className: 'my-list' }, child1, child2);
等價(jià)于(JSX寫(xiě)法)
var root =(
<ul className="my-list">
<li>First Text Content</li>
<li>Second Text Content</li>
</ul>
);
后者將XML語(yǔ)法直接加入JS中,通過(guò)代碼而非模板來(lái)高效的定義界面白粉。之后JSX通過(guò)翻譯器轉(zhuǎn)換為純JS再由瀏覽器執(zhí)行鼠渺。在實(shí)際開(kāi)發(fā)中鸭巴,JSX在產(chǎn)品打包階段都已經(jīng)編譯成純JavaScript拦盹,JSX的語(yǔ)法不會(huì)帶來(lái)任何性能影響。另外普舆,由于JSX只是一種語(yǔ)法,因此JavaScript的關(guān)鍵字class, for等也不能出現(xiàn)在XML中沼侣,而要如例子中所示,使用className, htmlFor代替蛾洛,這和原生DOM在JavaScript中的創(chuàng)建也是一致的养铸。JSX只是創(chuàng)建虛擬DOM的一種語(yǔ)法格式而已,除了用JSX,我們也可以用JS代碼來(lái)創(chuàng)建虛擬DOM.
2. JSX!=HTML
JSX形式上非常像常見(jiàn)的HTML,但它并不是一種標(biāo)記語(yǔ)言钞螟,它實(shí),是調(diào)用React.createElement函數(shù)鳞滨,所以在使用JSX時(shí),務(wù)必在頭部
import React from ‘react’;
拯啦。
JSX只是借鑒HTML的規(guī)則/規(guī)范:
- 開(kāi)始和結(jié)束標(biāo)簽配對(duì)
<組件>....</組件> - 無(wú)內(nèi)容的組件標(biāo)簽應(yīng)寫(xiě)為自封閉形式
<組件></組件>應(yīng)寫(xiě)為<組件 /> - 可自定義屬性澡匪,字符串值應(yīng)用雙引號(hào)仙蛉,其他值用{}括起來(lái)
<person name="Tom" age={30} married={true} />
- 布爾值可省略值
<person married />等價(jià)于<person married={true} /> -
必須單一子節(jié)點(diǎn)
- "空值"自動(dòng)忽略
<div />
<div></div>
<div>{false}</div>
<div>{true}</div>
<div>{null}</div>
<div>{undefined}</div>
//所以可以用來(lái)顯示或隱藏標(biāo)簽
<View>
{isShow && <Text>Warning</Text>} //此處若isShow為true,則返回text組件(并非true值)荠瘪,所以可以顯示
</View>
- 組件必須大寫(xiě)字母開(kāi)頭
- 文本必須寫(xiě)在Text組件內(nèi)
<View>
<Text>
你好嗎!
</Text>
</View>
- 注釋比較特殊是{/**/}赛惩,有別于js部分的//和/**/
{/*<View />*/}
- 只能嵌入表達(dá)式
//錯(cuò)誤寫(xiě)法
{if(true) {return <Text />}};
{for(let i=0; i<arr.length; i++) {....}};
//正確的寫(xiě)法
{isTrue && <Text />};
{arr.map(i=><Text>{i.text}</Text>)};
//如果是復(fù)雜的邏輯可以另寫(xiě)函數(shù)在這里只是調(diào)用
{doSomething()};
更多內(nèi)容篮绰,可看Introducint JSX
facebook.github.io/react/docs/introducing-jsx.html
JSX In Depth
https://facebook.github.io/react/docs/jsx-in-depth.html
三、初識(shí)React組件化開(kāi)發(fā)
首先季惯,介紹一款在線的模擬器
),非完整模擬勉抓,但是我們可以用來(lái)練習(xí)基礎(chǔ)。
1. class/function都可以作為積木(組件)
//class
class GoodMorning extends Component {
render() {
return (
<Text>GoodMorning</Text>
)
}
}
//function
const GoodEvening = () => {
return
(
<Text>GoodEvening</Text>
)
}
//都可以作為App的組件
export default class App extends Component {
render() {
return (
<View>
<GoodMorning />
<GoodEvening />
</View>
)
}
}
輸出:
GoodMorning
GoodEvening
2. 使用屬性props定制“積木”(組件)
class GoodMorning extends Component {
render() {
return (
<Text>GoodMorning,{this.props.name}</Text>
)
}
}
const GoodEvening = (props) => {
return
(
<Text>GoodEvening,{props.name}</Text>
)
}
export default class App extends Component {
render() {
return (
<View>
<GoodMorning name="Li" /> {/*使用時(shí)傳入屬性*/}
<GoodMorning name="Wang" /> {/*使用時(shí)傳入屬性*/}
</View>
)
}
}
輸出:
GoodMorning,Li
GoodEvening,Wang
3. defaultProps默認(rèn)值和propTypes類型約束
class Demo extends Component{
static defaultProps = {
name : 'WangDaChui',//賦值默認(rèn)值
}
static propTypes = {
name : React.propTypes.string,//約定類型為string
}
render...
}
defaultProps和propTypes寫(xiě)法類似(都為靜態(tài)成員屬性)藕筋。
propTypes只在開(kāi)發(fā)階段有效,發(fā)布時(shí)會(huì)被自動(dòng)移除隐圾。
根據(jù)編碼習(xí)慣愛(ài)好自由取舍。
4. 變量作用域
- 函數(shù)內(nèi)的局部變量暇藏,只能函數(shù)內(nèi)讀寫(xiě)蜜笤,函數(shù)運(yùn)行結(jié)束盐碱,自動(dòng)銷毀啊胶。
- class內(nèi)的成員變量,在單個(gè)class的實(shí)例內(nèi)讀寫(xiě)焰坪,實(shí)例銷毀時(shí),一并銷毀聘惦。使用時(shí),使用this善绎。
- class內(nèi)的靜態(tài)成員變量,在所有class的實(shí)例中共享禀酱,不會(huì)自動(dòng)銷毀。而且其他模塊可以通過(guò)此class訪問(wèn)(類public)剂跟。
- class外的變量减途,在所有class實(shí)例內(nèi)共享曹洽,不自動(dòng)銷毀。除非明確export送淆,否則其他模塊不可訪問(wèn)(類private)。
- global全局變量偷崩,任何地方都可讀寫(xiě)(類瀏覽器的window)辟拷,不自動(dòng)銷毀阐斜。
global.test = 1;
則以后任何地方都可以alert(global.test)
或alert(test)
。
5. class內(nèi)的成員變量寫(xiě)法
class Demo extends Component{
name = 'Tom'; //注意沒(méi)有任何let var聲明符號(hào)
render(){....}
}
//我們寫(xiě)的時(shí)候還是推薦上邊的寫(xiě)法智听。還有一種寫(xiě)法渡紫,是老寫(xiě)法到推,我們知道即可:
class Demo extends Component {
constructor(props) {
super(props); // 照抄即可惕澎,不可省略
this.xxx = 1; //聲明的成員變量
}
render() {
…….
}
}
6. 動(dòng)態(tài)生成組件列表與key
- 根據(jù)多個(gè)數(shù)據(jù)生成多個(gè)組件,我們一般使用map方法唧喉。注意捣卤,箭頭函數(shù)的返回值,如果有{}董朝,記得加return。
- 循環(huán)生成的組件需要有唯一的key值區(qū)分子姜,因?yàn)橛蠽irtual DOM(Virtual Dom我們后邊會(huì)介紹)祟绊。
{['a','b'].map(i=><Text key={i}>{i}</Text>)}
1.key屬性放在循環(huán)的直接容器上哥捕。
2.key值優(yōu)先使用區(qū)分度較高的值(id,具體內(nèi)容)遥赚,其次考慮數(shù)組下標(biāo)。
3.key值只需在當(dāng)前循環(huán)中不重復(fù)凫佛。
7. state
萬(wàn)物生長(zhǎng)靠太陽(yáng),界面變化靠狀態(tài)(state)
- 一切界面變化都是state的變化愧薛。
- state的修改必須通過(guò)setState()方法:
this.setState({ likes : 3, })
- setState是異步操作衣赶,修改不會(huì)馬上生效厚满。
看一段例子就能理解,定義碘箍、使用、修改:
export default class App extends Component {
state = { //定義state
likes : 2,
}
onPress = ()=>{
const {likes} = this.state;
this.setState({ //通過(guò)setState丰榴,修改state中的值
likes : likes+1,
}
)
}
render() {
return(
<View>
<TouchableOpacity onPress={this.onPress}>
<Text>{this.state.likes}</Text> //使用state中的值
</TouchableOpacity>
</View>
)
}
}
8. VIRTUAL DOM
狀態(tài)的變化會(huì)帶來(lái)界面的變化货邓,狀態(tài)不斷變化會(huì)帶來(lái)性能問(wèn)題嗎四濒?
React會(huì)自動(dòng)計(jì)算出差異部分,以最小的差異去重新渲染盗蟆,在內(nèi)存中“打草稿”的這一概念便稱為VIRTUAL DOM。
VIRTUAL DOM喳资,正式通過(guò)key來(lái)判斷哪些是已有的,哪些是新增的仆邓,以最小的差異去重新渲染鲜滩。