JSX
雖然 JSX 不是 React 必須使用的, 但是它是 React 推薦使用的, 因?yàn)樗梢远x簡(jiǎn)潔且我們熟知的包含屬性的樹(shù)狀結(jié)構(gòu)語(yǔ)法, 便于閱讀和維護(hù).
HTML標(biāo)簽 與 React組件 對(duì)比
React 可以渲染 HTML 標(biāo)簽 (strings) 或 React 組件 (classes).
要渲染 HTML 標(biāo)簽家肯,只需在 JSX 里使用小寫(xiě)字母開(kāi)頭的標(biāo)簽名.
var myDivElement = <div className="foo" />;
ReactDom.render(myDivElement, document.body);
要渲染 React 組件踪区,只需創(chuàng)建一個(gè)大寫(xiě)字母開(kāi)頭的本地變量.
class MyComponent extends React.Component {
render() {
return (<div></div>)
}
}
var myElement = <MyComponent someProperty={true} />;
ReactDom.render(myElement, document.body);
- React 的 JSX 里約定分別使用首字母大, 小寫(xiě)來(lái)區(qū)分本地組件的類(lèi)和 HTML 標(biāo)簽.
- 由于 JSX 就是 JavaScript, 一些標(biāo)識(shí)符像 class 和 for 不建議作為 XML 屬性名. 作為替代, React DOM 使用 className 和 htmlFor 來(lái)做對(duì)應(yīng)的屬性.
JavaScript 表達(dá)式
- 要使用 JavaScript 表達(dá)式作為屬性值, 只需把這個(gè)表達(dá)式用一對(duì)大括號(hào) ({}) 包起來(lái), 不要用引號(hào) (“”).
// 輸入 (JSX):
var person = <Person name={window.isLoggedIn ? window.name : ''} />;
// 輸出 (JS):
var person = React.createElement(
Person,
{name: window.isLoggedIn ? window.name : ''}
);
- JavaScript 表達(dá)式可用于描述子結(jié)點(diǎn).
// 輸入 (JSX):
var content = <Container>{window.isLoggedIn ? <View1 /> : <View2 />}</Container>;
// 輸出 (JS):
var content = React.createElement(
Container,
null,
window.isLoggedIn ? React.createElement(View1) : React.createElement(View2)
);
- JavaScript 表達(dá)式展示注釋. 我們只需要用 {/* 注釋 */} 就行.
Component
React 允許將代碼封裝成組件(component), 然后像插入普通 HTML 標(biāo)簽一樣, 在網(wǎng)頁(yè)中插入這個(gè)組件.
class Welcome extends React.Component {
render() {
return (
<div>es6 定義組件</div>
)
}
}
ReactDom.render(
<Welcome />,
document.getElementById("root")
)
有兩點(diǎn)需要注意: 組件類(lèi)的第一個(gè)字母需要大寫(xiě), 組件類(lèi)只能包含一個(gè)頂層標(biāo)簽.
ref 屬性
組件并不是真實(shí)的 DOM 節(jié)點(diǎn), 而是存在于內(nèi)存之中的一種數(shù)據(jù)結(jié)構(gòu), 叫做虛擬 DOM (virtual DOM). 只有當(dāng)它插入文檔以后, 才會(huì)變成真實(shí)的 DOM.
根據(jù) React 的設(shè)計(jì), 所有的 DOM 變動(dòng), 都先在虛擬 DOM 上發(fā)生, 然后再將實(shí)際發(fā)生變動(dòng)的部分, 反映在真實(shí) DOM 上, 這種算法叫做 DOM diff , 它可以極大提高網(wǎng)頁(yè)的性能表現(xiàn).
每個(gè)組件默認(rèn)都會(huì)一個(gè) ref
屬性, 我們能根據(jù)這個(gè)屬性獲取到真是的 DOM 節(jié)點(diǎn).
<input
type='text'
placeholder='請(qǐng)輸入內(nèi)容'
id='input'
// 受控組件的用法
// onChange={(event) => {
// this.setState({
// value: event.target.value
// })
// }}
// 非受控組件的用法
// 非受控組件將數(shù)據(jù)保存在Dom中, 方便直接使用
ref={(inputText) => {this.inputText = inputText}}
/>
對(duì)于文本輸入框, 我們可以根據(jù) ref 來(lái)直接拿到真實(shí) DOM 節(jié)點(diǎn)中的用戶(hù)輸入.
我們也可以通過(guò) this.refs.refName
來(lái)直接獲取到真實(shí)的 DOM 節(jié)點(diǎn). 也就是組件的對(duì)象. 拿到組件的對(duì)象, 我們可以讀寫(xiě)對(duì)象的變量, 調(diào)用對(duì)象的函數(shù)等.
當(dāng)然我們也不能過(guò)度使用 ref, 畢竟拿到的是真實(shí) DOM 節(jié)點(diǎn), 如果虛擬節(jié)點(diǎn)的數(shù)據(jù)沒(méi)有及時(shí)更新到真實(shí)節(jié)點(diǎn), 那么操作真實(shí)節(jié)點(diǎn)就會(huì)出錯(cuò). 以下幾個(gè)實(shí)際時(shí)機(jī)適合使用 ref 屬性.
- 管理文本框用戶(hù)輸入, 文本選擇, 媒體播放.
- 一定會(huì)發(fā)生的動(dòng)畫(huà).
- 與第三方DOM庫(kù)集成.
組件的生命周期
這張圖 清晰的展示了組件的生命周期.
后記
React 所涉及到的概念我并沒(méi)有全部寫(xiě)上去, 如果以后遇到有趣的知識(shí)點(diǎn)再做補(bǔ)充.