react入門

最近在學(xué)習(xí)react,希望有系統(tǒng)的資料呜象,這篇文章適合入門:
React可以在瀏覽器運(yùn)行孽惰,也可以在服務(wù)器運(yùn)行晚岭,但是在這為了盡量保持簡單,且React語法是一致的勋功,服務(wù)器的用法和瀏覽器差別不大坦报,在這只涉及瀏覽器。
一. HTML模板
使用React的網(wǎng)頁源碼狂鞋,結(jié)構(gòu)大致如下:

<!DOCTYPE html>
<html >
  <head>
     <script type="text/javascript" src="react.min.js"></script>
     <script type="text/javascript" src="JSXTransformer.js"></script>
  </head>
  <body>
    <div id="example" ></div>
      <script type="text/jsx">
       //Our code goes here!
      </script>
  </body>
</html>

注意:
1.最后一個script標(biāo)簽的type屬性為text/jsx片择。這是因?yàn)镽eact獨(dú)有的JSX語法,跟JavaScript不兼容骚揍。凡是使用JSX的地方字管,都要加上type=”text/jsx”。
2.React提供兩個庫:react.js和JSXTransformer.js疏咐,它們必須首先加載纤掸,其中JSXTransformer.js的作用是將JSX語法轉(zhuǎn)為JavaScript語法。這一步很消耗時間浑塞,實(shí)際上線的時候借跪,應(yīng)該將它放到服務(wù)器完成。
$ jsx src/ build/:這個命令可以將src子目錄的js文件進(jìn)行語法轉(zhuǎn)換酌壕,轉(zhuǎn)碼后的文件全部放在build子目錄掏愁。

二. React.render()
React.render是React的最基本方法,用于將模板轉(zhuǎn)為HTML語言卵牍,并插入指定的DOM節(jié)點(diǎn)果港。
實(shí)例一:

<!DOCTYPE html>
<html >
<head>
    <script src="es5-shim.min.js"></script>
    <script src="es5-sham.min.js"></script>
    <script src="console-polyfill.js"></script>
    <script type="text/javascript" src="react.min.js"></script>
    <script type="text/javascript" src="JSXTransformer.js"></script>
</head>
<body>
<div id="example" ></div>

<script type="text/jsx">
    React.render(
        <h1>Hello,World</h1>, 
        document.getElementById("example")
    );
    </script>
</body>
</html>

運(yùn)行效果:

image

三. JSX語法
HTML語言直接寫在JavaScript語言之中,不加任何引號糊昙,這就是JSX的語法辛掠,它允許HTML與JavaScript的混寫。
實(shí)例二:

<!DOCTYPE html>
<html >
<head>
    <script src="es5-shim.min.js"></script>
    <script src="es5-sham.min.js"></script>
    <script src="console-polyfill.js"></script>
    <script type="text/javascript" src="react.min.js"></script>
    <script type="text/javascript" src="JSXTransformer.js"></script>
</head>
<body>
<div id="example" ></div>

<script type="text/jsx">
    var names = ['Alice','Emily','Kate'];
    React.render(
        <div>
        {
            names.map(function(name) {
                return <div>Hello,{name}!</div>
            })
        }
        </div>, 
        document.getElementById("example")
    );
    </script>
</body>
</html>

運(yùn)行效果:

image
    上面代碼體現(xiàn)了JSX的基本語法規(guī)則:遇到HTML標(biāo)簽(以<開頭)释牺,就用HTML規(guī)則解析萝衩;遇到代碼塊(以{開頭},就用JavaScript規(guī)則解析没咙。 
    JSX允許直接在模板插入JavaScript變量猩谊。如果這個變量是一個數(shù)組,則會展開這個數(shù)組的所有成員

實(shí)例三:

<html >
<head>
    <script src="es5-shim.min.js"></script>
    <script src="es5-sham.min.js"></script>
    <script src="console-polyfill.js"></script>
    <script type="text/javascript" src="react.min.js"></script>
    <script type="text/javascript" src="JSXTransformer.js"></script>
</head>
<body>
<div id="example" ></div>

<script type="text/jsx">
    var arr = [
        <h1>Hello world!</h1>,
        <h2>React is awesome</h2>
    ];
    React.render(
        <div>{arr}</div>, 
        document.getElementById("example")
    );
    </script>
</body>
</html>
    上面代碼的arr變量是一個數(shù)組祭刚,結(jié)果JSX會把它的所有成員牌捷,添加到模板墙牌,運(yùn)行結(jié)果如下:

image

四. 組件
React允許將代碼封裝成組件(component),然后像插入普通HTML標(biāo)簽一樣暗甥,在網(wǎng)頁中插入這個組件喜滨。React.createClass方法就用于生成一個組件類。
實(shí)例四:

<!DOCTYPE html>
<html >
<head>
    <script src="es5-shim.min.js"></script>
    <script src="es5-sham.min.js"></script>
    <script src="console-polyfill.js"></script>
    <script type="text/javascript" src="react.min.js"></script>
    <script type="text/javascript" src="JSXTransformer.js"></script>
</head>
<body>
<div id="example" ></div>

<script type="text/jsx">
    var HelloMessage = React.createClass({
        render: function() {
            return <h1>Hello {this.props.name}</h1>;
        }
    });
    React.render(
        <HelloMessage name="John"/>, 
        document.getElementById("example")
    );
    </script>
</body>
</html>

運(yùn)行效果:

image
    上面代碼中淋袖,變量HelloMessage就是一個組件類鸿市。模板插入<HelloMessage/>時,會自動生成HelloMessage的一個實(shí)例(下文的“組件”都指組件類的實(shí)例)即碗。所有組件類都必須有自已的render方法焰情,用于輸出組件。 
    組件的用法與原生的HTML標(biāo)簽完全一致剥懒,可以任意加入屬性内舟,比如<HelloMessage name=”John”/>,就是HelloMessage組件加入一個name屬性初橘,值為John验游。組件的屬性可以在組件類的this.props對象上獲取,比如name屬性就可以通過this.props.name讀取保檐。 
    添加組件屬性耕蝉,有一個地方需要注意,就是class屬性需要寫成className夜只,for屬性需要寫成htmlFor垒在,這是因?yàn)閏lass和for是JavaScript的保留字。

五. this.props.children
this.props對象的屬性與組件的屬性一一對應(yīng)扔亥,但是有一個例外场躯,就是this.props.children屬性。它表示組件的所有子節(jié)點(diǎn)旅挤。
實(shí)例五:

<!DOCTYPE html>
<html >
<head>
    <script src="es5-shim.min.js"></script>
    <script src="es5-sham.min.js"></script>
    <script src="console-polyfill.js"></script>
    <script type="text/javascript" src="react.min.js"></script>
    <script type="text/javascript" src="JSXTransformer.js"></script>
</head>
<body>

<script type="text/jsx">
    var NotesList = React.createClass({
        render:function() {
            return (
                <ol>
                {
                    this.props.children.map(function(child) {
                        return <li>{child}</li>
                    })
                }
                </ol>
            );
        }
    });
    React.render(
        <NotesList>
            <span>hello</span>
            <span>world</span>
        </NotesList>,
        document.body
    );
    </script>
</body>
</html>
    上面代碼的NoteList組件有兩個span子節(jié)點(diǎn)踢关,它們都可以通過this.props.children讀取,運(yùn)行結(jié)果如下:
image
    這里需要注意粘茄,只有當(dāng)子節(jié)點(diǎn)多于1個時签舞,this.props.children才是一個數(shù)組,否則是不能用map方法的柒瓣,會報錯瘪菌。

六. React.findDOMNode()
組件并不是真實(shí)的DOM節(jié)點(diǎn),而是存在于內(nèi)存之中的一種數(shù)據(jù)結(jié)構(gòu)嘹朗,叫做虛擬DOM(virtual DOM)。只有當(dāng)它插入文檔之后诵肛,才會變成真實(shí)的DOM屹培。根據(jù)React的設(shè)計(jì)默穴,所有的DOM變動,都先在虛擬DOM上發(fā)生褪秀,然后再將實(shí)際發(fā)生變動的部分蓄诽,反映在真實(shí)DOM上,這種算法叫做DOM diff媒吗,它可以極大提高網(wǎng)頁的性能仑氛。
但是,有時需要從組件獲取真實(shí)DOM的節(jié)點(diǎn)闸英,這時就要用到React.findDOMNode方法锯岖。
實(shí)例六:

<html >
<head>
    <script src="es5-shim.min.js"></script>
    <script src="es5-sham.min.js"></script>
    <script src="console-polyfill.js"></script>
    <script type="text/javascript" src="react.min.js"></script>
    <script type="text/javascript" src="JSXTransformer.js"></script>
</head>
<body>
<div id="example" ></div>

<script type="text/jsx">
    var MyComponent = React.createClass({
        handleClick: function() {
            React.findDOMNode(this.refs.myTextInput).focus();
        },
        render: function() {
            return (
                <div>
                    <input type="text" ref="myTextInput"/>
                    <input type="button" value="Focus the text input" onClick={this.handleClick}/>
                </div>
            );
        }
    });
    React.render(
        <MyComponent/>,
        document.getElementById('example')
    );
    </script>
</body>
</html>

運(yùn)行效果:

image
    上面代碼中,組件MyComponent的子節(jié)點(diǎn)有一個文本輸入框甫何,用于獲取用戶的輸入出吹。這時就必須獲取真實(shí)的DOM節(jié)點(diǎn),虛擬DOM是拿不到用戶輸入的辙喂。為了做到這一點(diǎn)捶牢,文本輸入框必須有一個ref屬性,然后this.refs.[refName]就指向這個虛擬DOM的子節(jié)點(diǎn)巍耗,最后通過React.findDOMNode方法獲取真實(shí)DOM的節(jié)點(diǎn)秋麸。 
    需要注意的是,由于React.findDOMNode方法獲取的是真實(shí)DOM炬太,所以必須等到虛擬DOM插入文檔以后灸蟆,才能使用這個方法,否則會返回null娄琉。上面代碼中次乓,通過為組件指定Click事件的回調(diào)函數(shù),確保了只有等到真實(shí)DOM發(fā)生Click事件之后孽水,才會調(diào)用React.findDOMNode方法票腰。 
    React組件支持很多事件,除了Click事件以外女气,還有KeyDown杏慰、Copy、Scroll等炼鞠,完整的事件清單請查看官方文檔缘滥。

七. this.state
組件免不子要與用戶互動,React的一大創(chuàng)新谒主,就是將組件看成是一個狀態(tài)機(jī)朝扼,一開始有一個初始狀態(tài),然后用戶互動霎肯,導(dǎo)致狀態(tài)變化擎颖,從而觸發(fā)重新渲染UI榛斯,如下實(shí)例所示。
實(shí)例七:

<html >
<head>
    <script src="es5-shim.min.js"></script>
    <script src="es5-sham.min.js"></script>
    <script src="console-polyfill.js"></script>
    <script type="text/javascript" src="react.min.js"></script>
    <script type="text/javascript" src="JSXTransformer.js"></script>
</head>
<body>
<div id="example" ></div>

<script type="text/jsx">
    var LikeButton = React.createClass({
        getInitialState: function() {
            return {liked:false};
        },
        handleClick: function(event) {
            this.setState({liked:!this.state.liked});
        },
        render: function() {
            var text = this.state.liked?'like':'haven\'t liked';
            return (
                <p onClick={this.handleClick}>
                    You {text} this.click to toggle.
                </p>
            );
        }
    });
    React.render(
        <LikeButton/>,
        document.getElementById('example')
    );
    </script>
</body>
</html>

運(yùn)行效果:


image
    點(diǎn)擊上面這行搂捧,將會變成如下內(nèi)容 
image
    再次點(diǎn)擊驮俗,會變回初始內(nèi)容,即點(diǎn)擊內(nèi)容會交替變換允跑。

    上面代碼是一個LikeButton組件王凑,它的getInitialState方法用于定義初始狀態(tài),也就是一個對象聋丝,這個對象可以通過this.state屬性讀取索烹。當(dāng)用戶點(diǎn)擊組件,導(dǎo)致狀態(tài)變化潮针,this.setState方法就修改狀態(tài)值术荤,每次修改以后,自動調(diào)用this.render方法每篷,再次渲染組件瓣戚。 
    由于this.props和this.state都用于描述組件的特性,可能會產(chǎn)生混淆焦读。一個簡單的區(qū)分方法是子库,this.props表示那些一旦定義,就不再改變的特性矗晃,而this.state是會隨著用戶互動而產(chǎn)生變化的特性仑嗅。

八. 表單
用戶在表單填入的內(nèi)容,屬于用戶跟組件的互動张症,所以不能用this.props讀取仓技。如下實(shí)例所示。
實(shí)例八:

<html >
<head>
    <script src="es5-shim.min.js"></script>
    <script src="es5-sham.min.js"></script>
    <script src="console-polyfill.js"></script>
    <script type="text/javascript" src="react.min.js"></script>
    <script type="text/javascript" src="JSXTransformer.js"></script>
</head>
<body>

<script type="text/jsx">
    var Input = React.createClass({
        getInitialState: function() {
            return {value:'Hello!'};
        },
        handleChange: function(event) {
            this.setState({value:event.target.value});
        },
        render: function() {
            var value=this.state.value;
            return (
                <div>
                    <input type="text" value={value} onChange={this.handleChange}/>
                    <p>{value}</p>
                </div>
            );
        }
    });
    React.render(
        <Input/>,
        document.body
    );
    </script>
</body>
</html>

運(yùn)行效果:


image
    上面代碼中俗他,文本輸入框的值脖捻,不能用this.props.value讀取,而要定義一個onChange事件的回調(diào)函數(shù)兆衅,通過event.target.value讀取用戶輸入的值地沮。textarea元素、select元素羡亩、radio元素都屬于這種情況摩疑,更多介紹請參考官方文檔。

九. 組件的生命周期
組件的生命周期分成三個狀態(tài):
Mounting:已插入真實(shí)DOM
Updating:正在被重新渲染
Unmounting:已移出真實(shí)DOM
React為每個狀態(tài)都提供了兩種處理函數(shù)畏铆,will函數(shù)在進(jìn)入狀態(tài)之前調(diào)用雷袋,did函數(shù)在進(jìn)入狀態(tài)之后調(diào)用,三種狀態(tài)共計(jì)五種處理函數(shù)辞居。
componentWillMount()
componentDidMount()
componentWillUpdate(object nextProps, object nextState)
componentDidUpdate(object prevProps, object prevState)
componentWillUnmount()
此外片排,React還提供兩種特殊狀態(tài)的處理函數(shù)寨腔。
componentWillReceiveProps(object nextProps):已加載組件收到新的參數(shù)時調(diào)用
shouldComponentUpdate(object nextProps, object nextState):組件判斷是否重新渲染時調(diào)用
這些方法的詳細(xì)說明,可以參考官方文檔率寡。
實(shí)例九:

<html >
<head>
    <script src="es5-shim.min.js"></script>
    <script src="es5-sham.min.js"></script>
    <script src="console-polyfill.js"></script>
    <script type="text/javascript" src="react.min.js"></script>
    <script type="text/javascript" src="JSXTransformer.js"></script>
</head>
<body>

<script type="text/jsx">
    var Hello = React.createClass({ 
      getInitialState: function() { 
        return { 
          opacity: 1.0 
        }; 
      }, 
      componentDidMount: function() { 
        this.timer = setInterval(function () { 
          var opacity = this.state.opacity; 
          opacity -= .05; 
          if (opacity < 0.1) { 
            opacity = 1.0; 
          }  
          this.setState({ 
            opacity: opacity 
          });  
        }.bind(this), 100); 
      }, 
      render: function() {
        return (
            <div style={{opacity: this.state.opacity}}>
                Hello {this.props.name}
            </div>
        ); 
        }
    });

    React.render(
        <Hello name="world"/>,
        document.body
    );
</script>
</body>
</html>

運(yùn)行效果:


image

上面代碼在hello組件加載以后,通過componentDidMount方法設(shè)置一個定時器倚搬,每隔100毫秒冶共,就重新設(shè)置組件的透明度,從而引發(fā)重新渲染每界。
另外捅僵,組件的style屬性的設(shè)置方式也值得注意,不能寫成

style="opacity:{this.state.opacity};"

而要寫成

style={{opacity:this.state.opacity}}

這是因?yàn)镽eact組件樣式是一個對象眨层,所以第一重大括號表示這是JavaScript語法庙楚,第二重大括號表示樣式對象。

十. Ajax
組件的數(shù)據(jù)來源趴樱,通常是通過Ajax請求從服務(wù)器獲取馒闷,可以使用componentDidMount方法重新渲染UI。
實(shí)例十:

<html >
<head>
    <script src="es5-shim.min.js"></script>
    <script src="es5-sham.min.js"></script>
    <script src="console-polyfill.js"></script>
    <script type="text/javascript" src="react.min.js"></script>
    <script type="text/javascript" src="JSXTransformer.js"></script>
    <script type="text/javascript" src="jquery-1.8.3.js"></script>
</head>
<body>

<script type="text/jsx">
    var UserGist = React.createClass({ 
      getInitialState: function() {
        return {
            username:'',
            lastGistUrl:''
        };
      },
      componentDidMount: function() {
        $.get(this.props.source, function(result) {
            var lastGist = result[0];
            if(this.isMounted()) {
                this.setState({
                    username:lastGist.owner.login,
                    lastGistUrl:lastGist.html_url
                });
            }
        }.bind(this));
      },
      render: function() {
        return (
            <div>
                {this.state.username}'s last gist is 
                <a href={this.state.lastGistUrl}>here</a>.
            </div>
        );
      }
    });

    React.render(
        <UserGist source="https://api.github.com/users/octocat/gists"/>,
        document.body
    );
</script>
</body>
</html>
    上面代碼使用jQuery完成Ajax請求叁征,這是為了便于說明纳账。React沒有任何依賴,完全可以使用其他庫捺疼。

出處:http://www.iteye.com

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末疏虫,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子啤呼,更是在濱河造成了極大的恐慌卧秘,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件官扣,死亡現(xiàn)場離奇詭異翅敌,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)醇锚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進(jìn)店門哼御,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人焊唬,你說我怎么就攤上這事恋昼。” “怎么了赶促?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵液肌,是天一觀的道長。 經(jīng)常有香客問我鸥滨,道長嗦哆,這世上最難降的妖魔是什么谤祖? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮老速,結(jié)果婚禮上粥喜,老公的妹妹穿的比我還像新娘。我一直安慰自己橘券,他們只是感情好额湘,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著旁舰,像睡著了一般锋华。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上箭窜,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天毯焕,我揣著相機(jī)與錄音,去河邊找鬼磺樱。 笑死纳猫,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的坊罢。 我是一名探鬼主播续担,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼活孩!你這毒婦竟也來了物遇?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤憾儒,失蹤者是張志新(化名)和其女友劉穎询兴,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體起趾,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡诗舰,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了训裆。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片眶根。...
    茶點(diǎn)故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖边琉,靈堂內(nèi)的尸體忽然破棺而出属百,到底是詐尸還是另有隱情,我是刑警寧澤变姨,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布族扰,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏渔呵。R本人自食惡果不足惜怒竿,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望扩氢。 院中可真熱鬧耕驰,春花似錦、人聲如沸录豺。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽巩检。三九已至,卻和暖如春示启,著一層夾襖步出監(jiān)牢的瞬間兢哭,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工夫嗓, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留迟螺,地道東北人。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓舍咖,卻偏偏與公主長得像矩父,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子排霉,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評論 2 353

推薦閱讀更多精彩內(nèi)容

  • 原教程內(nèi)容詳見精益 React 學(xué)習(xí)指南窍株,這只是我在學(xué)習(xí)過程中的一些閱讀筆記,個人覺得該教程講解深入淺出攻柠,比目前大...
    leonaxiong閱讀 2,833評論 1 18
  • It's a common pattern in React to wrap a component in an ...
    jplyue閱讀 3,264評論 0 2
  • 深入JSX date:20170412筆記原文其實(shí)JSX是React.createElement(componen...
    gaoer1938閱讀 8,061評論 2 35
  • 按照慣例球订,先給ReactJS背書 React是一個Facebook開發(fā)的UI庫,于2013年5月開源瑰钮,并迅速的從最...
    艾倫先生閱讀 3,234評論 1 12
  • “那到了DENVER一定記得給Michael兄發(fā)信件冒滩,否則他該擔(dān)心了±饲矗”二刀流還是叮囑了一下萌舞开睡。 “好的,一定記...
    闡釋逐暗閱讀 328評論 0 1