React 入門實(shí)例教程
現(xiàn)在最熱門的前端框架,毫無疑問是React。
上周,基于 React 的React Native發(fā)布,結(jié)果一天之內(nèi),就獲得了 5000 顆星,受矚目程度可見一斑。
React 起源于 Facebook 的內(nèi)部項(xiàng)目,因?yàn)樵摴緦κ袌錾纤蠮avaScript MVC 框架,都不滿意,就決定自己寫一套,用來架設(shè)Instagram的網(wǎng)站。做出來以后,發(fā)現(xiàn)這套東西很好用,就在2013年5月開源了。
由于 React 的設(shè)計(jì)思想極其獨(dú)特,屬于革命性創(chuàng)新,性能出眾,代碼邏輯卻非常簡單。所以,越來越多的人開始關(guān)注和使用,認(rèn)為它可能是將來 Web 開發(fā)的主流工具。
這個(gè)項(xiàng)目本身也越滾越大,從最早的UI引擎變成了一整套前后端通吃的 Web App 解決方案。衍生的 React Native 項(xiàng)目,目標(biāo)更是宏偉,希望用寫 Web App 的方式去寫 Native App。如果能夠?qū)崿F(xiàn),整個(gè)互聯(lián)網(wǎng)行業(yè)都會(huì)被顛覆,因?yàn)橥唤M人只需要寫一次 UI ,就能同時(shí)運(yùn)行在服務(wù)器、瀏覽器和手機(jī)(參見《也許,DOM 不是答案》)。
既然 React 這么熱門,看上去充滿希望,當(dāng)然應(yīng)該好好學(xué)一下。從技術(shù)角度,可以滿足好奇心,提高技術(shù)水平;從職業(yè)角度,有利于求職和晉升,有利于參與潛力大的項(xiàng)目。但是,好的 React 教程卻不容易找到,這一方面因?yàn)檫@項(xiàng)技術(shù)太新,剛剛開始走紅,大家都沒有經(jīng)驗(yàn),還在摸索之中;另一方面因?yàn)?React 本身還在不斷變動(dòng),API 一直在調(diào)整,至今沒發(fā)布1.0版。
我學(xué)習(xí) React 時(shí),就很苦惱。有的教程討論一些細(xì)節(jié)問題,對入門沒幫助;有的教程寫得不錯(cuò),但比較短,無助于看清全貌。我斷斷續(xù)續(xù)學(xué)了幾個(gè)月,看過二十幾篇教程,在這個(gè)過程中,將對自己有幫助的 Demo 都收集下來,做成了一個(gè)庫React Demos。
下面,我就根據(jù)這個(gè)庫,寫一篇全面又易懂的 React 入門教程。你只需要跟著每一個(gè) Demo 做一遍,就能初步掌握 React 。當(dāng)然,前提是你必須擁有基本 JavaScript 和 DOM 知識(shí),但是你讀完就會(huì)發(fā)現(xiàn),React 所要求的預(yù)備知識(shí)真的很少。
零、安裝
React 的安裝包,可以到官網(wǎng)下載。不過,React
Demos
已經(jīng)自帶 React 源碼,不用另外安裝,只需把這個(gè)庫拷貝到你的硬盤就行了。
$ git clone git@github.com:ruanyf/react-demos.git
如果你沒安裝 git, 那就直接下載zip 壓縮包。
下面要講解的12個(gè)例子在各個(gè)Demo
子目錄,每個(gè)目錄都有一個(gè)index.html
文件,在瀏覽器打開這個(gè)文件(大多數(shù)情況下雙擊即可),就能立刻看到效果。
需要說明的是,React 可以在瀏覽器運(yùn)行,也可以在服務(wù)器運(yùn)行,但是本教程只涉及瀏覽器。一方面是為了盡量保持簡單,另一方面 React 的語法是一致的,服務(wù)器的用法與瀏覽器差別不大。Demo13
是服務(wù)器首屏渲染的例子,有興趣的朋友可以自己去看源碼。
使用 React 的網(wǎng)頁源碼,結(jié)構(gòu)大致如下。
上面代碼有兩個(gè)地方需要注意。首先,最后一個(gè)標(biāo)簽的
type
屬性為text/babel
。這是因?yàn)? React 獨(dú)有的 JSX 語法,跟 JavaScript 不兼容。凡是使用 JSX 的地方,都要加上type="text/babel"
。
其次,上面代碼一共用了三個(gè)庫:react.js
、react-dom.js
和Browser.js
,它們必須首先加載。其中,react.js
是
React 的核心庫,react-dom.js
是提供與 DOM 相關(guān)的功能,Browser.js
的作用是將
JSX 語法轉(zhuǎn)為 JavaScript 語法,這一步很消耗時(shí)間,實(shí)際上線的時(shí)候,應(yīng)該將它放到服務(wù)器完成。
$ babel src --out-dir build
上面命令可以將src
子目錄的js
文件進(jìn)行語法轉(zhuǎn)換,轉(zhuǎn)碼后的文件全部放在build
子目錄。
ReactDOM.render 是 React 的最基本方法,用于將模板轉(zhuǎn)為 HTML 語言,并插入指定的 DOM 節(jié)點(diǎn)。
ReactDOM.render(
Hello, world!
, document.getElementById('example') );
上面代碼將一個(gè)h1
標(biāo)題,插入example
節(jié)點(diǎn)(查看demo01
),運(yùn)行結(jié)果如下。
三、JSX 語法
上一節(jié)的代碼, HTML 語言直接寫在 JavaScript 語言之中,不加任何引號(hào),這就是JSX 的語法,它允許
HTML 與 JavaScript 的混寫(查看Demo02
)。
var names = ['Alice', 'Emily', 'Kate']; ReactDOM.render(
{ names.map(function (name) { return, document.getElementById('example') );Hello, {name}!}) }
上面代碼體現(xiàn)了 JSX 的基本語法規(guī)則:遇到 HTML 標(biāo)簽(以<
開頭),就用 HTML 規(guī)則解析;遇到代碼塊(以{
開頭),就用
JavaScript 規(guī)則解析。上面代碼的運(yùn)行結(jié)果如下。
JSX 允許直接在模板插入 JavaScript 變量。如果這個(gè)變量是一個(gè)數(shù)組,則會(huì)展開這個(gè)數(shù)組的所有成員(查看demo03
)。
var arr = [
Hello world!
,React is awesome
, ]; ReactDOM.render({arr}, document.getElementById('example') );
上面代碼的arr
變量是一個(gè)數(shù)組,結(jié)果 JSX 會(huì)把它的所有成員,添加到模板,運(yùn)行結(jié)果如下。
四、組件
React 允許將代碼封裝成組件(component),然后像插入普通 HTML 標(biāo)簽一樣,在網(wǎng)頁中插入這個(gè)組件。React.createClass 方法就用于生成一個(gè)組件類(查看demo04
)。
var HelloMessage = React.createClass({ render: function() { return
Hello {this.props.name}
; } }); ReactDOM.render(, document.getElementById('example') );
上面代碼中,變量HelloMessage
就是一個(gè)組件類。模板插入
時(shí),會(huì)自動(dòng)生成HelloMessage
的一個(gè)實(shí)例(下文的"組件"都指組件類的實(shí)例)。所有組件類都必須有自己的render
方法,用于輸出組件。
注意,組件類的第一個(gè)字母必須大寫,否則會(huì)報(bào)錯(cuò),比如HelloMessage
不能寫成helloMessage
。另外,組件類只能包含一個(gè)頂層標(biāo)簽,否則也會(huì)報(bào)錯(cuò)。
var HelloMessage = React.createClass({ render: function() { return
Hello {this.props.name}
some text
; } });
上面代碼會(huì)報(bào)錯(cuò),因?yàn)?code style="margin:auto 3px; padding:0px 5px; list-style-type:none; border:none; display:inline-block; font-size:15.6px; background-color:pink">HelloMessage組件包含了兩個(gè)頂層標(biāo)簽:h1
和p
。
組件的用法與原生的 HTML 標(biāo)簽完全一致,可以任意加入屬性,比如
,就是HelloMessage
組件加入一個(gè)name
屬性,值為John
。組件的屬性可以在組件類的this.props
對象上獲取,比如name
屬性就可以通過this.props.name
讀取。上面代碼的運(yùn)行結(jié)果如下。
添加組件屬性,有一個(gè)地方需要注意,就是class
屬性需要寫成className
,for
屬性需要寫成htmlFor
,這是因?yàn)?code style="margin:auto 3px; padding:0px 5px; list-style-type:none; border:none; display:inline-block; font-size:15.6px; background-color:pink">class和for
是
JavaScript 的保留字。
this.props
對象的屬性與組件的屬性一一對應(yīng),但是有一個(gè)例外,就是this.props.children
屬性。它表示組件的所有子節(jié)點(diǎn)(查看demo05
)。
var NotesList = React.createClass({ render: function() { return (
{ React.Children.map(this.props.children, function (child) { return
); } }); ReactDOM.render(- {child}
; }) }hello world , document.body );
上面代碼的NoteList
組件有兩個(gè)span
子節(jié)點(diǎn),它們都可以通過this.props.children
讀取,運(yùn)行結(jié)果如下。
欲知詳情,請下載word文檔 下載文檔