React Native 語法指南

React Native真的是越來越流行,沒使用React Native開發(fā)項目都不好意思說自己是搞客戶端開發(fā)的观堂。對于純Native開發(fā)者來說氮凝,剛上手React Native有一定的適應期凹蜂,如果JavaScript也不熟練的話那就更悲催了弟头。React Native涉及ES6,React語法踩验,JSX鸥诽,前端調試,Native客戶端等知識箕憾,本文簡單總結了React Native開發(fā)中一些知識點牡借。算是在學習中的積累。

Component


Component:組件袭异,使用React.createClass或者extends React.Component創(chuàng)建的類為組件钠龙。
Element:元素或者可以說是組件的實例,使用<Label />或者let label = new Label()創(chuàng)建的為實例御铃。

對于定義組件碴里,React以前版本的寫法(ES5):

var Lable  = React.createClass({

    render(){
    
    }
});

React最新的寫法(ES6):

class Label extends React.Component{
    render(){
    }
}

props與state


props屬性:組件可以定義初始值,自己不可更改props屬性值上真,只允許從父組件中傳遞過來:

// 父組件
class MainComponent extends React.Component{
    render(){
        return(<Label name="標題欄">);
    }
}

// 子組件
class Label extends React.Component{
    render(){
        return(<Text>{this.props.name}</Text>);
    }
}

父組件向Label傳遞name="標題欄"的props屬性咬腋,在Label中使用this.props.name引用此屬性。

state屬性:組件用來改變自己狀態(tài)的屬性睡互,通常使用setState({key:value})來改變屬性值根竿,不能使用this.state.xxx來直接改變陵像,setState({key:value})方法會觸發(fā)界面刷新。

對于經常改變的數(shù)據(jù)且需要刷新界面顯示寇壳,可以使用state醒颖。對于不需要改變的屬性值可以使用props。React Native建議由頂層的父組件定義state值壳炎,并將state值作為子組件的props屬性值傳遞給子組件泞歉,這樣可以保持單一的數(shù)據(jù)傳遞。

在以前版本的React中定義state匿辩,props可以使用生命周期方法 getInitialState()getInitialState():

var Label = React.createClass({
    getInitialState(){
        key:value,
        ...
    },
    getInitialProps(){
        key:value,
        ...
    },// 這種寫法需要有疏日,不要使用;
    render:funation(){
        
    }
});

在最新版本的React可以使用構造函數(shù)替代getInitialState()撒汉,getInitialState()方法定義初始值:

class Label extends React.Component{
   constructor(props) {
       super(props);
       this.state = {
           time: '2016',
           city: '上海',
       };
       this.props = {
           name:'標題',
       };
   }
}

默認props與props校驗


class Label extends React.Component{
   constructor(props) {
       super(props);
   }

  // 默認props
  static defaultProps = {
     city: '南京',
     index: 12,
  }
   
  // propTypes用于驗證轉入的props,當向 props 傳入無效數(shù)據(jù)時涕滋,JavaScript 控制臺會拋出警告
  static propTypes = {
     city: React.PropTypes.string.isRequired,
     index: React.PropTypes.number.isRequired,
  }

  state = {
     city: this.props.city,
     index:this.props.index,
  }
}

// or

class Label extends React.Component{
   constructor(props) {
       super(props);
   }
}

// 默認props
Label.defaultProps = {
   city: '南京',
   index: 12,
}

// propTypes用于驗證轉入的props睬辐,當向 props 傳入無效數(shù)據(jù)時,JavaScript 控制臺會拋出警告
Label.propTypes = {
   city: React.PropTypes.string.isRequired,
   index: React.PropTypes.number.isRequired,
}

生命周期


我們把組件從裝載,到渲染宾肺,再到卸載當做一次生命周期溯饵,也就是組件的生存狀態(tài)從裝載開始到卸載為止,期間可以根據(jù)屬性的變化進行多次渲染锨用。

生命周期的三種狀態(tài):

  • Mounting:裝載丰刊,
  • Updating:渲染
  • Unmounting:卸載
componentWillMount(),組件開始裝載之前調用增拥,在一次生命周期中只會執(zhí)行一次啄巧。
componentDidMount(),組件完成裝載之后調用掌栅,在一次生命周期中只會執(zhí)行一次秩仆,從這里開始就可以對組件進行各種操作了,比如在組件裝載完成后要顯示的時候執(zhí)行動畫猾封。
componentWillUpdate(object nextProps, object nextState)澄耍,組件屬性更新之前調用,每一次屬性更新都會調用
componentDidUpdate(object prevProps, object prevState)晌缘,組件屬性更新之后調用齐莲,每次屬性更新都會調用
componentWillUnmount(),組件卸載之前調用

組件屬性更改時會調用以下方法磷箕,在一次生命周期中可以執(zhí)行多次:

componentWillReceiveProps(object nextProps)选酗,已加載組件收到新的參數(shù)時調用
shouldComponentUpdate(object nextProps, object nextState),組件判斷是否重新渲染時調用

頁面跳轉


初始化第一個頁面:

import SeatPageComponent from './SeatPageComponent';
import MainPageComponent from './MainPageComponent';
import TrainListComponent from './TrainListComponent';

class MainPage extends React.Component {
    render() {
        let defaultName = 'MainPageComponent';
        let defaultComponent = MainPageComponent;
        return (
            <Navigator
                // 指定默認頁面
                initialRoute={{ name: defaultName, component: defaultComponent }}
                // 配置頁面間跳轉動畫
                configureScene={(route) => {
                    return Navigator.SceneConfigs.VerticalDownSwipeJump;
                }}
                // 初始化默認頁面
                renderScene={(route, navigator) => {
                    let Component = route.component;
                    // 將navigator作為props傳遞到下一個頁面
                    return <Component {...route.params} navigator={navigator} />
                }} />
        );
    }
}

跳轉到下一頁面:

jumpToNext(){
      const { navigator } = this.props;// 由上一個頁面?zhèn)鬟f過來
      if(navigator) {
          navigator.push({
              name: 'SeatPageComponent',
              component: SeatPageComponent,// 下一個頁面
          });
      }
}

返回上一個頁面:

 _back(){
     const { navigator } = this.props;
     if(navigator) {
         navigator.pop();
     }
 }

頁面間通信


例如:從A頁面打開B頁面
A通過route.params將參數(shù)傳遞給B:

jumpToNext(){ 
    const { navigator } = this.props;// 由上一個頁面?zhèn)鬟f過來
    if(navigator) { 
        navigator.push({ 
            name: 'SeatPageComponent', 
            component: SeatPageComponent,// 下一個頁面 
            params: { // 需要傳遞個下一個頁面的參數(shù),第二個頁面使用this.props.xxx獲取參數(shù)
                id: 123,
                title: this.state.title, 
            },
        });
     }
}

A通過route.params傳遞回調方法或者A的引用來讓B將數(shù)據(jù)傳回給A:


// A頁面
jumpToNext(){ 
    const { navigator } = this.props;// 由上一個頁面?zhèn)鬟f過來
    if(navigator) { 
        let that = this;// this作用域岳枷,參見下文函數(shù)綁定
        navigator.push({ 
            name: 'SeatPageComponent', 
            component: SeatPageComponent,// 下一個頁面 
            params: { // 需要傳遞個下一個頁面的參數(shù),第二個頁面使用this.props.xxx獲取參數(shù)
                title: '測試',
                getName: function(name) {that.setState({ name: name })}
            },
        });
     }
}

// B頁面
 _back(){
     const { navigator } = this.props;
     if(this.props.getName){
         this.props.getName('測試');
     }
     if(navigator) {
         navigator.pop();
     }
 }

組件間通信


父組件-->子組件星掰, 使用props多望,父組件向子組件傳遞props

// 父組件
class MainComponent extends React.Component{
    render(){
        return(<Label name="標題欄">);
    }
}

// 子組件
class Label extends React.Component{
    render(){
        return(<Text>{this.props.name}</Text>);
    }
}

子組件-->父組件, 父組件在創(chuàng)建子組件時傳遞回調方法

// 父組件
class MainComponent extends React.Component{
    constructor(props) {
        super(props);
        this.state = {
            name: '測試',
        };
    }
  
    // 回調方法
    getName(str){
         this.setState({name:str});
    }

    render(){
        return(<Label name="標題欄" getName={getName}/>);
    }
}

// 子組件
class Label extends React.Component{
    render(){
        return(
            <View>
                  <TouchableOpacity onPress={()=>this._onPress()}>
                          <Text>點我氢烘,{this.props.name}</Text>
                  </TouchableOpacity>
            </View>);
    }

    _onPress(){
          if(this.props.getName){
              this.props.getName('測試')
          }
    }
}

非父子關系的組件怀偷,即沒有任何嵌套關系的組件, 可以引入訂閱源(js-signals, PubSubJS)播玖,監(jiān)聽訂閱事件椎工。例如,在生命周期方法中addEventListener()蜀踏,removeEventListener()维蒙,在合適時機setState()。

ECMAScript


ES6中函數(shù)的寫法:

class Label extends React.Component{
    doSomething(){
        //...
    }// 不要使用逗號或者分號作為結尾
}

key:value形式定義函數(shù)的寫法:

var Label = React.createClass({
    doSomething:funation(){
        //......
    },// 需要使用逗號作為結尾果覆,不能使用分號
    doSomething2:function(){
        //......
    },
});

函數(shù)綁定

class Label extends React.Component{

    // 有函數(shù)
    sayHello(str){
        console.log(str)
    }

    // 在onPress中使用箭頭函數(shù)調用
    // onPress={() => this.sayHello('Hello')}
    
    // 等同于
    //onPress={sayHello('hello').bind(this)} 

    // 等同于
    // onPress={print('hello',this)}

    render(){
        return (
              <View>
                   <TouchableOpacity onPress={() => this.sayHello('Hello')}>
                          <Text>點我</Text>
                   </TouchableOpacity>
              </View>
        )
    }

    function print(str,this){
        let that = this;// 注意這里this的生命周期
        function say(str){
            that.sayHello(str)// 此處不能再使用this
        }
        say(str);
    }
}

Tips


require颅痊,import:javascript的模塊管理工具,管理各個模塊之間的引用局待,解決javascript異步加載的問題斑响,解決js寫成多個文件后瀏覽器加載緩慢的問題。

JavaScript中沒有private钳榨,public的概念
使用_開頭的方法代表private方法舰罚,不適用則表示public方法

class Label extends Component{
    // private 函數(shù)
    _doSomething(){
        //......
    }
    
    // public 函數(shù)
    doSomething(){
        //......
    }
}

參考資料
Reactjs中文教程
極客學院React教程
ECMAScript語法
JavaScript模塊系統(tǒng)
require.js
Navigator
結合ES6+開發(fā)React
React組件通信

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市薛耻,隨后出現(xiàn)的幾起案子营罢,更是在濱河造成了極大的恐慌,老刑警劉巖饼齿,帶你破解...
    沈念sama閱讀 212,383評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件饲漾,死亡現(xiàn)場離奇詭異,居然都是意外死亡缕溉,警方通過查閱死者的電腦和手機能颁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來倒淫,“玉大人伙菊,你說我怎么就攤上這事〉型粒” “怎么了镜硕?”我有些...
    開封第一講書人閱讀 157,852評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長返干。 經常有香客問我兴枯,道長,這世上最難降的妖魔是什么矩欠? 我笑而不...
    開封第一講書人閱讀 56,621評論 1 284
  • 正文 為了忘掉前任财剖,我火速辦了婚禮悠夯,結果婚禮上,老公的妹妹穿的比我還像新娘躺坟。我一直安慰自己沦补,他們只是感情好,可當我...
    茶點故事閱讀 65,741評論 6 386
  • 文/花漫 我一把揭開白布咪橙。 她就那樣靜靜地躺著夕膀,像睡著了一般。 火紅的嫁衣襯著肌膚如雪美侦。 梳的紋絲不亂的頭發(fā)上产舞,一...
    開封第一講書人閱讀 49,929評論 1 290
  • 那天,我揣著相機與錄音菠剩,去河邊找鬼易猫。 笑死,一個胖子當著我的面吹牛具壮,可吹牛的內容都是我干的准颓。 我是一名探鬼主播,決...
    沈念sama閱讀 39,076評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼嘴办,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了买鸽?” 一聲冷哼從身側響起涧郊,我...
    開封第一講書人閱讀 37,803評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎眼五,沒想到半個月后妆艘,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 44,265評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡看幼,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,582評論 2 327
  • 正文 我和宋清朗相戀三年批旺,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片诵姜。...
    茶點故事閱讀 38,716評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡汽煮,死狀恐怖,靈堂內的尸體忽然破棺而出棚唆,到底是詐尸還是另有隱情暇赤,我是刑警寧澤,帶...
    沈念sama閱讀 34,395評論 4 333
  • 正文 年R本政府宣布宵凌,位于F島的核電站鞋囊,受9級特大地震影響,放射性物質發(fā)生泄漏瞎惫。R本人自食惡果不足惜溜腐,卻給世界環(huán)境...
    茶點故事閱讀 40,039評論 3 316
  • 文/蒙蒙 一译株、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧挺益,春花似錦歉糜、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至黍檩,卻和暖如春叉袍,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背刽酱。 一陣腳步聲響...
    開封第一講書人閱讀 32,027評論 1 266
  • 我被黑心中介騙來泰國打工喳逛, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人棵里。 一個月前我還...
    沈念sama閱讀 46,488評論 2 361
  • 正文 我出身青樓润文,卻偏偏與公主長得像,于是被迫代替她去往敵國和親殿怜。 傳聞我的和親對象是個殘疾皇子典蝌,可洞房花燭夜當晚...
    茶點故事閱讀 43,612評論 2 350

推薦閱讀更多精彩內容

  • 自己最近的項目是基于react的,于是讀了一遍react的文檔头谜,做了一些記錄(除了REFERENCE部分還沒開始讀...
    潘逸飛閱讀 3,360評論 1 10
  • 原教程內容詳見精益 React 學習指南骏掀,這只是我在學習過程中的一些閱讀筆記,個人覺得該教程講解深入淺出柱告,比目前大...
    leonaxiong閱讀 2,813評論 1 18
  • JSX 知識準備 JSX 并不是一門全新的語言截驮,僅僅是一個語法糖,允許開發(fā)者在javascript中編寫XML語言...
    艾倫先生閱讀 4,500評論 4 20
  • <一>編寫Hello World React Native看起來很像React际度,只不過其基礎組件是原生組件而非we...
    AFinalStone閱讀 1,023評論 0 2
  • 妹子說自己不喜歡和男生聊天葵袭?不可能,不是你心理有問題(或者同性戀)乖菱,就是身邊男生太渣坡锡。看一看你身邊的同學窒所,你會發(fā)現(xiàn)...
    無恙志閱讀 5,900評論 4 15