React Native 語法指南

React Native真的是越來越流行,沒使用React Native開發(fā)項目都不好意思說自己是搞客戶端開發(fā)的。對于純Native開發(fā)者來說,剛上手React Native有一定的適應(yīng)期,如果JavaScript也不熟練的話那就更悲催了。React Native涉及ES6,React語法,JSX,前端調(diào)試,Native客戶端等知識,本文簡單總結(jié)了React Native開發(fā)中一些知識點。算是在學(xué)習(xí)中的積累。

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="標(biāo)題欄">);
    }
}

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

父組件向Label傳遞name="標(biāo)題欄"的props屬性,在Label中使用this.props.name引用此屬性。

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

對于經(jīng)常改變的數(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可以使用構(gòu)造函數(shù)替代getInitialState(),getInitialState()方法定義初始值:

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

默認props與props校驗


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

  // 默認props
  static defaultProps = {
     city: '南京',
     index: 12,
  }
   
  // propTypes用于驗證轉(zhuǎn)入的props,當(dāng)向 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用于驗證轉(zhuǎn)入的props,當(dāng)向 props 傳入無效數(shù)據(jù)時,JavaScript 控制臺會拋出警告
Label.propTypes = {
   city: React.PropTypes.string.isRequired,
   index: React.PropTypes.number.isRequired,
}

生命周期


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

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

  • Mounting:裝載,
  • Updating:渲染
  • Unmounting:卸載
componentWillMount(),組件開始裝載之前調(diào)用,在一次生命周期中只會執(zhí)行一次。
componentDidMount(),組件完成裝載之后調(diào)用,在一次生命周期中只會執(zhí)行一次,從這里開始就可以對組件進行各種操作了,比如在組件裝載完成后要顯示的時候執(zhí)行動畫。
componentWillUpdate(object nextProps, object nextState),組件屬性更新之前調(diào)用,每一次屬性更新都會調(diào)用
componentDidUpdate(object prevProps, object prevState),組件屬性更新之后調(diào)用,每次屬性更新都會調(diào)用
componentWillUnmount(),組件卸載之前調(diào)用

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

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

頁面跳轉(zhuǎn)


初始化第一個頁面:

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 }}
                // 配置頁面間跳轉(zhuǎn)動畫
                configureScene={(route) => {
                    return Navigator.SceneConfigs.VerticalDownSwipeJump;
                }}
                // 初始化默認頁面
                renderScene={(route, navigator) => {
                    let Component = route.component;
                    // 將navigator作為props傳遞到下一個頁面
                    return <Component {...route.params} navigator={navigator} />
                }} />
        );
    }
}

跳轉(zhuǎn)到下一頁面:

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傳遞回調(diào)方法或者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="標(biāo)題欄">);
    }
}

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

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

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

    render(){
        return(<Label name="標(biāo)題欄" 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('測試')
          }
    }
}

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

ECMAScript


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

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

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

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

函數(shù)綁定

class Label extends React.Component{

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

    // 在onPress中使用箭頭函數(shù)調(diào)用
    // 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中文教程
極客學(xué)院React教程
ECMAScript語法
JavaScript模塊系統(tǒng)
require.js
Navigator
結(jié)合ES6+開發(fā)React
React組件通信

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 自己最近的項目是基于react的,于是讀了一遍react的文檔,做了一些記錄(除了REFERENCE部分還沒開始讀...
    潘逸飛閱讀 3,750評論 1 10
  • 原教程內(nèi)容詳見精益 React 學(xué)習(xí)指南,這只是我在學(xué)習(xí)過程中的一些閱讀筆記,個人覺得該教程講解深入淺出,比目前大...
    leonaxiong閱讀 2,954評論 1 18
  • <一>編寫Hello World React Native看起來很像React,只不過其基礎(chǔ)組件是原生組件而非we...
    AFinalStone閱讀 1,091評論 0 2
  • 妹子說自己不喜歡和男生聊天?不可能,不是你心理有問題(或者同性戀),就是身邊男生太渣。看一看你身邊的同學(xué),你會發(fā)現(xiàn)...
    無恙志閱讀 6,147評論 4 15
  • 五年前,你來到我的世界!醫(yī)生把粉粉嫩嫩的你放在我的胸口,那一刻,我感覺擁有了全世界,滿心滿眼都是你。把你放進眼里都...
    靈雀子閱讀 1,115評論 4 6

友情鏈接更多精彩內(nèi)容