(中間因為應付各種考試,處理其他事情,隔了好時間沒更新,現在終於有時間了,續上!)
本文為React初始體驗,因此先不考慮文件如何組織,盡量以最簡單的方式讓大家了解React其中的原理。
在創建組件(component)之前,大家首先需要了解一些基礎知識。有ES6、JSX語法等基礎知識的同學請跳過下面一段。
ES6是JavaScript的最新標准,里面新增了許多語法方式,甚至出現了“類”的繼承方式,我個人暫且把他們理解為新增了許多“語法糖”,這些“語法糖”可能帶給老手的是方便,而對於我們這些菜鳥來說就是一種理解負擔,但必須要看,因為這就是趨勢。JSX語法,大家就姑且認為是一種能將js和html寫在一起處理的語法。以上內容不展開講,有時間會專門開一篇文章,不知道的童鞋可以先自行百度一下。
下面開始今天的正題,One、Two、Three、Action……
React的原理其實非常簡單,請看下圖:
一句話說上面的關系:動作會影響狀態數據的變化,狀態數據的變化造成組件變化,組件變了有可能會造成新的動作產生,從而再影響狀態數據變化……
組件(component):給大家舉個“栗子”,相信大家都刷微博吧,微博中的每一條信息都相當於有一個小面板來展示信息,這個小面板里面有發該條微博人的頭像,微博內容,插圖,以及“轉發”、“評論”、“點贊”, 這個小面板我們就可以理解成是一個總組件,面板中的每個部分又可以認為是小組件,小組件組成了最終的大組件。因為每條微博的組成內容類似,所以我們只需要創建這樣一個面板組件,重復使用。組件中都有個props屬性,這個屬性中存放組件的初始狀態的量,通過this.props.<變量名>來調用,通過getDefaultProps()來設置默認初始的prop屬性值,通過propTypes來設置props的類型、是否必須有等。
動作(action):這個應該都熟悉,像什么onClick,onChange,onBlur等,這兒有React支持的所有事件,這些動作需要執行的內容如何定義后面會講到。
狀態數據(state):這是React的核心部分,組件的變化就是因為state的變化引起的。state與props類似,區別是props一旦設定一般不去改變它,但是動作(action)的變化會引起狀態數據(state)的隨時變化,從而重新渲染組件(component)引起變化。通過getInitialState()來設置默認的狀態,通過this.setState()來改變狀態值。
說了這么多,開始實戰吧!!!
1、創建一個文件夾,用於存放這個示例的所有文件,我將他命名為“ReactApp”,然后cd到這個文件夾下npm安裝上一篇文章中提到的所有組件。
2、新建名為App.jsx 的文件,這就是我們提到的用於創建組件的地方。下面的大致結構是:一個總的組件MyComponent包含兩個子組件Component1和Component2,且name屬性由總組件通過props屬性由上向下傳遞到各個子組件。
1 import React from 'react';//引入react模塊,用來創建組件 2 3 var MyComponent= React.createClass({//創建總組件,記得組件名一定要大寫哦!不然會報錯!!! 4 render: function() { 5 return ( 6 <div> 7 <Component1 name={this.props.name}/>//通過props傳遞name屬性 8 <Component2 name={this.props.name}/> 9 </div> 10 ); 11 } 12 }); 13 14 var Component1 = React.createClass({//創建子組件Component1 15 getDefaultProps:function () { //設置初始Props 16 return { 17 inputValue:'隨便寫些啥', 18 }; 19 }, 20 getInitialState:function () { //設置初始State 21 return { 22 content:"Hello World", 23 }; 24 }, 25 handleClick:function () { //用戶自己定義的動作函數 26 this.setState({content:"就是"+this.refs.myTextInput.value+"!!!"});//用於修改state 27 }, 28 handleChange:function () { //用戶自己定義的動作函數 29 this.setState({content:this.refs.myTextInput.value}); 30 }, 31 render:function () { //組件渲染函數,最外層只能有一個標簽!!!!! 32 return ( 33 <div> 34 <h1>{this.props.name}:Component1</h1> 35 <input type="text" ref="myTextInput" placeholder={this.props.inputValue} onChange={this.handleChange} /> 36 <input type="button" value="點擊" onClick={this.handleClick} /> 37 <h3>{this.state.content}</h3> 38 </div> 39 ); 40 }, 41 }); 42 43 var Component2 = React.createClass({//創建子組件Component2 44 45 getInitialState:function(){//設置state的默認初始值 46 return{ 47 counter:0, 48 }; 49 }, 50 handleAdd:function () {//action函數,state加一 51 this.state.counter+=1; 52 this.setState({counter:this.state.counter});//設置當前的state值 53 }, 54 handleMinus:function () {//action函數,state減一 55 this.state.counter-=1; 56 this.setState({counter:this.state.counter}); 57 }, 58 handleBack:function () {//action函數,state歸零 59 this.state.counter=0; 60 this.setState({counter:this.state.counter}); 61 }, 62 render:function(){//組件渲染 63 return( 64 <div> 65 <h1>{this.props.name}:Component2</h1> 66 <input type="button" value="Add 1" onClick={this.handleAdd} /> 67 <input type="button" value="Minus 1" onClick={this.handleMinus} /> 68 <input type="button" value="Back 0" onClick={this.handleBack} /> 69 <h2>{this.state.counter}</h2> 70 </div> 71 ); 72 }, 73 }); 74 export {MyComponent} ;//組件輸出,(這兒插一句題外話,export是ES6制定的模塊加載方式,與import配合使用,而exports是CommonJS的標准,與require等配合使用,他們的區別有機會另開文章將)
3、組件雖然建好了,但是瀏覽器不會認識這種形式的組件,這時候就需要用到react提供的另一個庫“react-dom”,它的作用是將組件渲染到真正的dom樹上,很簡單新建文件名為main.js的文件。
1 import React from 'react';//引入“react”組件 2 import ReactDOM from 'react-dom';//引入“react-dom”組件 3 import {MyComponent} from './App.jsx';//引入我們剛才寫好的MyComponent組件 4 ReactDOM.render(<MyComponent name="chen" />,document.getElementById('app'));//將組件渲染到dom頁面的app節點中,並向子組件傳輸name屬性
卡!到此為止,組件的創建的流程基本說完了,下一篇文章主要會講如何將這個組件在NodeJS下利用Webpack打包並以熱加載模式,讓他真正跑起來,最后一片文章更完后我會將整個例子放在github上,有興趣的同學可以去看看,試試。下面是效果圖
寫在最后的n段話:
1、React的優勢在於它首先會創建一個虛擬dom,就像我們上面寫的組件,如果組件中的數據有更新,它不會直接去操作瀏覽器中的真實dom,而是先在自己創建的虛擬組件中利用diff算法,找出不同的地方修改,然后將其渲染到瀏覽器上。沒有對真實dom大量的操作也就意味着瀏覽器端渲染速度加快,這基本就是React的核心所在。
2、在創建組件(Component)的時候,我們只用到了其中的一少部分函數或者屬性,還有沒有用到的如:
①propTypes,它是一個Json對象,用於設置組件中props屬性的類型,如number,string等,保證屬性的安全性;
②組件在渲染的時候會有幾個狀態,react官方把它叫做Lifecycle Methods,其實就是設置在組件渲染到瀏覽器前要做什么,渲染后做什么,對應的API如下:
componentWillMount();//組件渲染前
componentDidMount();//組件渲染完成后
componentWillUpdate();//由於Action驅動,組件在更新前
componentDidUpdate();//組件在更新完成后
componentWillReceiveProps();//組件在接受到props之前
。。。還有好多關於組件變化狀態的函數,可以點這兒查詢。
作者: GeoChen
出處: http://www.cnblogs.com/GeoChen>
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出, 原文鏈接 如有問題, 可郵件(giser_xiaochen@163.com)咨詢.