1.Hello world

import React, { Component } from 'react';
import { AppRegistry, Text } from 'react-native';

class myFirstApp extends Component {
  render() {
    return (
      <Text>Hello world!</Text>
    );
  }
}

AppRegistry.registerComponent('myFirstApp', () => myFirstApp);

2.Props(属性)

class Greeting extends Component {
  render() {
    return (
      <View>
        <Text>Hello {this.props.name}</Text>
      </View>
    );
  }
}
export default class myFirstApp extends Component {
  render() {
    return (
        <View style={{ alignItems: 'center' }}>
            <Greeting name='react!' />
            <Greeting name='react-native' />
            <Greeting name='android' />
        </View>
    )
  }
}

3.State(状态)

在constructor中初始化state,然后在需要修改时调用setState方法。

constructor(props){
    super(props);
    this.state = {
        count: 0,
    }
}
doUpdateCount(){
    this.setState({
        count: this.state.count+1
    })
}

<Text>当前计数是:{this.state.count}</Text>
<TouchableOpacity onPress={this.doUpdateCount.bind(this)} style={{padding: 5,backgroundColor: '#ccc'}}>
      <Text>点我开始计数</Text>
</TouchableOpacity>

4.样式

<View>
   <Text style={[styles.bigblue],{backgroundColor: '#0f0'}}>style set</Text>
   <Text style={[styles.bigblue, {backgroundColor: '#00f'}]}>style set</Text>
   <Text style={{color:'#f00'}}>just red</Text>
   <Text style={styles.red}>just red</Text>
   <Text style={styles.bigblue}>just bigblue</Text>
   <Text style={[styles.bigblue, styles.red]}>bigblue, then red</Text>
   <Text style={[styles.red, styles.bigblue]}>red, then bigblue</Text>
</View>

const styles = StyleSheet.create({
  bigblue: {
    color: 'blue',
    fontWeight: 'bold',
    fontSize: 30,
  },
  red: {
    color: 'red',
  },
});

5.高度与宽度

(1)指定宽高
React Native中的尺寸都是无单位的,表示的是与设备像素密度无关的逻辑像素点。

<View>
    <View style={{width: 50, height: 50, backgroundColor: 'powderblue'}} />
    <View style={{width: 100, height: 100, backgroundColor: 'skyblue'}} />
    <View style={{width: 150, height: 150, backgroundColor: 'steelblue'}} />
</View>

(2)弹性(Flex)宽高

使用flex:1来指定某个组件扩张以撑满所有剩余的空间。如果有多个并列的子组件使用了flex:1,则这些子组件会平分父容器中剩余的空间。如果这些并列的子组件的flex值不一样,则谁的值更大,谁占据剩余空间的比例就更大。
组件能够撑满剩余空间的前提是其父容器的尺寸不为零。如果父容器既没有固定的width和height,也没有设定flex,则父容器的尺寸为零。其子组件如果使用了flex,也是无法显示的。

<View style={{flex: 1}}>
   <View style={{flex: 1, backgroundColor: 'powderblue'}} />
   <View style={{flex: 2, backgroundColor: 'skyblue'}} />
   <View style={{flex: 3, backgroundColor: 'steelblue'}} />
</View>

(3)react native没有宽高100%的设置,所以如果需要让元素撑满屏幕,需要:

import { Dimensions, View } from 'react-native';
<View style={{width: Dimensions.get('window').width,height: Dimensions.get('window').height}} />

6.使用Flexbox布局

flexDirection的默认值是column而不是row,flex也只能指定一个数字值。
flexDirection可以决定布局的主轴。子元素是应该沿着水平轴(row)方向排列,还是沿着竖直轴(column)方向排列呢?默认值是竖直轴(column)方向。
justifyContent可以决定其子元素沿着主轴的排列方式。子元素是应该靠近主轴的起始端还是末尾段分布呢?亦或应该均匀分布?对应的这些可选项有:flex-start,center,flex-end,space-around以及space-between
alignItems可以决定其子元素沿着次轴(与主轴垂直的轴,比如若主轴方向为row,则次轴方向为column)的排列方式。子元素是应该靠近次轴的起始端还是末尾段分布呢?亦或应该均匀分布?对应的这些可选项有:flex-start,center,flex-end以及stretch

      <View style={{
        flex: 1,
        flexDirection: 'column',
        justifyContent: 'center',
        alignItems: 'center',
      }}>
        <View style={{width: 50, height: 50, backgroundColor: 'powderblue'}} />
        <View style={{width: 50, height: 50, backgroundColor: 'skyblue'}} />
        <View style={{width: 50, height: 50, backgroundColor: 'steelblue'}} />
      </View>

7.处理文本输入

TextInput是一个允许用户输入文本的基础组件。它有一个名为onChangeText的属性,此属性接受一个函数,而此函数会在文本变化时被调用。另外还有一个名为onSubmitEditing的属性,会在文本被提交后(用户按下软键盘上的提交键)调用(注意react中的onChange对应的是rn中的onChangeText)。

constructor(props) {
    super(props);
    this.state = {text: ''};
  }

  render() {
    return (
      <View style={{padding: 10}}>
        <TextInput
          style={{height: 40}}
          placeholder="Type here to translate!"
          onChangeText={(textCont) => this.setState({text:textCont})}
        />
        <Text style={{padding: 10, fontSize: 42}}>
          {this.state.text.split(' ').map((word) => word && 'xhh').join()}
        </Text>
      </View>
    );
  }

8.ScrollView

import React, { Component } from 'react';
import { ScrollView, View } from 'react-native';

export default class MyScrollView extends Component {
    getScrollViewList(){
        let scrollViewList = [];
        let colorList = ['red','green','blue','purple'];
        for(let i=0;i<colorList.length;i++) {
            var ViewItem = <View key={i} style={{ width: 420, height: 150, backgroundColor: colorList[i] }}></View>;
            scrollViewList.push(ViewItem);
        }
        console.log(scrollViewList);
        return scrollViewList;
    }
    render(){
        return (
            <ScrollView horizontal={true}>            
                { this.getScrollViewList() }
            </ScrollView>
            )
    }
}

如果页面内容一屏展示不完,需要滚动观看那就可以使用ScrollView了。

9.ListView

ListView组件用于显示一个垂直的滚动列表,其中的元素之间结构近似而仅数据不同。
ListView更适于长列表数据,且元素个数可以增删。和ScrollView不同的是,ListView并不立即渲染所有元素,而是优先渲染屏幕上可见的元素。
ListView组件必须的两个属性是dataSource和renderRow。dataSource是列表的数据源,而renderRow则逐个解析数据源中的数据,然后返回一个设定好格式的组件来渲染。
rowHasChanged函数也是ListView的必需属性。这里我们只是简单的比较两行数据是否是同一个数据(===符号只比较基本类型数据的值,和引用类型的地址)来判断某行数据是否变化了。

import React, { Component } from 'react';
import { ListView, Text, View } from 'react-native';

export class ListViewBasics extends Component {
  // 初始化模拟数据
  constructor(props) {
    super(props);
    const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
    this.state = {
      dataSource: ds.cloneWithRows([
        'John', 'John', 'James', 'Jimmy', 'Jackson', 'Jillian', 'Julie', 'Devin'
      ])
    };
  }
  render() {
    return (
      <View style={{flex: 1,width: 150,height: 100,marginTop: 5, marginBottom: 5 }}>
        <ListView
          dataSource={this.state.dataSource}
          renderRow={(myRowData) => <Text>{myRowData}</Text>}
        />
      </View>
    );
  }
}

10.网络

import React, { Component } from 'react';
import { TouchableOpacity, Text, View } from 'react-native';

export default class FetchAjax extends Component {
  constructor(){
    super();
    this.state = {
      textDesc: 'initialText',
    }
  }
  // 初始化模拟数据
  getData(){
    fetch('http://facebook.github.io/react-native/movies.json')
    .then((response) => response.json())
    .then((responseJson) => {
        console.log(responseJson);
        this.setState({
          textDesc: responseJson.movies[0].title,
        }) 
    })
    .catch((error) => {
        console.error(error);
    });
  }
  render() {
    return (
        <View>
            <TouchableOpacity style={{ padding: 5,borderWidth:1, borderColor:'#aaa',borderRadius:4 }} onPress={this.getData.bind(this)} >
              <Text>Click Get Data</Text>
            </TouchableOpacity>
            <Text>{this.state.textDesc}</Text> 
        </View>
    );
  }
}

11.路由Navigator

导航方法:
如果你得到了一个navigator对象的引用(译注:再次推荐仔细阅读此教程,理解如何在renderScene方法中传递navigator对象,否则直接调用会报undefined错误),则可以调用许多方法来进行导航:
getCurrentRoutes() - 获取当前栈里的路由,也就是push进来,没有pop掉的那些。
jumpBack() - 跳回之前的路由,当然前提是保留现在的,还可以再跳回来,会给你保留原样。
jumpForward() - 上一个方法不是调到之前的路由了么,用这个跳回来就好了。
jumpTo(route) - 跳转到已有的场景并且不卸载。
push(route) - 跳转到新的场景,并且将场景入栈,你可以稍后跳转过去
pop() - 跳转回去并且卸载掉当前场景
replace(route) - 用一个新的路由替换掉当前场景
replaceAtIndex(route, index) - 替换掉指定序列的路由场景
replacePrevious(route) - 替换掉之前的场景
resetTo(route) - 跳转到新的场景,并且重置整个路由栈
immediatelyResetRouteStack(routeStack) - 用新的路由数组来重置路由栈
popToRoute(route) - pop到路由指定的场景,在整个路由栈中,处于指定场景之后的场景将会被卸载。
popToTop() - pop到栈中的第一个场景,卸载掉所有的其他场景。
属性:
configureScene [function]
可选的函数,用来配置场景动画和手势。会带有两个参数调用,一个是当前的路由,一个是当前的路由栈。然后它应当返回一个场景配置对象。具体有哪些可以看这个目录:
node_modules/react-native/Libraries/CustomComponents/Navigator/NavigatorSceneConfigs.js

(route, routeStack) => Navigator.SceneConfigs.FloatFromRight
Navigator.SceneConfigs.PushFromRight (默认)
Navigator.SceneConfigs.FloatFromRight
Navigator.SceneConfigs.FloatFromLeft
Navigator.SceneConfigs.FloatFromBottom
Navigator.SceneConfigs.FloatFromBottomAndroid
Navigator.SceneConfigs.FadeAndroid
Navigator.SceneConfigs.HorizontalSwipeJump
Navigator.SceneConfigs.HorizontalSwipeJumpFromRight
Navigator.SceneConfigs.VerticalUpSwipeJump
Navigator.SceneConfigs.VerticalDownSwipeJump

initialRoute [object]
定义启动时加载的路由。路由是导航栏用来识别渲染场景的一个对象。initialRoute必须是initialRouteStack中的一个路由。initialRoute默认为initialRouteStack中最后一项。
initialRouteStack [object]
提供一个路由集合用来初始化。如果没有设置初始路由的话则必须设置该属性。如果没有提供该属性,它将被默认设置成一个只含有initialRoute的数组。
navigationBar [node]
可选参数,提供一个在场景切换的时候保持的导航栏。
navigator [object]
可选参数,提供从父导航器获得的导航器对象。
onDidFocus [function]
每当导航切换完成或初始化之后,调用此回调,参数为新场景的路由。
onWillFocus [function]
会在导航切换之前调用,参数为目标路由。
renderScene [function]
必要参数。用来渲染指定路由的场景。调用的参数是路由和导航器。

(route, navigator) =>
  <MySceneComponent title={route.title} navigator={navigator} />

sceneStyle [View#style]
将会应用在每个场景的容器上的样式。

index.android.js:

  configureScene(route){
     if(route.name == 'FirstPage'){
      return Navigator.SceneConfigs.FloatFromBottom
     }
     return Navigator.SceneConfigs.FloatFromRight;
  }
  renderScene(router, navigator){
      let Component = router.component;
      switch(router.name){
        case "FirstPage":
          Component = FirstPage;
          break;
        case "SecondPage":
          Component = MySecondPage;
          break;
      }
      return <Component {...router.params} navigator={navigator} />
  }
  renderHead(){
      return(
        <View style={{height:60,position:'absolute',top:0,left:0,right:0,backgroundColor:'#666',justifyContent: 'center',alignItems: 'center',borderWidth:1,borderColor:'#ccc'}}>
            <Text>
              {'Navigator Bar'}
            </Text>
        </View>
      )
  }

<Navigator
    navigationBar = {this.renderHead()}
    initialRoute={{name: 'FirstPage'}}
    configureScene={this.configureScene}
    renderScene={this.renderScene.bind(this)} />

navigator.js:

import React, { Component } from 'react';
import { Text, View, TouchableOpacity } from 'react-native';
import MySecondPage from './navigatorPage';

export default class FirstPage extends Component {
    onPressButton() {
        this.props.navigator.push({
          component: MySecondPage,
          params : {
            param1 : 'param1Value'
          },
          type: 'Bottom'
        })
        console.log(this.props.navigator.getCurrentRoutes());
    }
    componentWillUnmount(){
        console.log('FirstPage-componentWillUnmount');
    }
    render(){
      return(
        <View style={{marginTop: 60, flex:1,justifyContent: 'center',alignItems: 'center',}}>
            <Text>{'first Page'}</Text>
            <TouchableOpacity onPress={()=>this.onPressButton()}>
               <Text>点击跳转到第二页</Text>
            </TouchableOpacity>
        </View>
      )
    }
}

navigatorPage.js:

import React, { Component } from 'react';
import { Text, View, TouchableOpacity } from 'react-native';
import MyThirdPage from './navigatorOtherPage';

export default class MySecondPage extends Component {
    onPressButton() {
      this.props.navigator.push({
          component: MyThirdPage,
          type: 'Right'
      })
      console.log(this.props.param1); //param1Value
      console.log(this.props.navigator.getCurrentRoutes());
    }
    componentWillUnmount(){
        console.log('MySecondPage-componentWillUnmount');
    }
    render(){
      return(
        <View style={{marginTop: 60, flex:1,justifyContent: 'center',alignItems: 'center',}}>
            <Text>{'second Page'}</Text>
            <TouchableOpacity onPress={()=>this.onPressButton()}>
           <Text>点击跳转到第三页</Text>
        </TouchableOpacity>
        </View>
      )
    }
}

navigatorOtherPage.js:

import React, { Component } from 'react';
import { Text, View, TouchableOpacity } from 'react-native';
import FirstPage from './navigator';
import MySecondPage from './navigatorPage';

export default class MyThirdPage extends Component {
    // <TouchableOpacity onPress={()=>this.props.navigator.pop()}>
    //   <Text>返回到第二页</Text>
    // </TouchableOpacity>
    // <TouchableOpacity onPress={()=>this.props.navigator.replace({component: FirstPage})}>
    //   <Text>返回到第一页</Text>
    // </TouchableOpacity>

    // 就只执行了一次
    // <TouchableOpacity onPress={()=>this.props.navigator.replaceAtIndex({component: FirstPage}, 2)}>
    //   <Text>返回到第一页</Text>
    // </TouchableOpacity>
    // <TouchableOpacity onPress={()=>this.props.navigator.replaceAtIndex({component: MySecondPage}, 2)}>
    //   <Text>返回到第二页</Text>
    // </TouchableOpacity>

    // <TouchableOpacity onPress={()=>this.props.navigator.resetTo({component: FirstPage})}>
    //   <Text>返回到第一页</Text>
    // </TouchableOpacity>
    // <TouchableOpacity onPress={()=>this.props.navigator.resetTo({component: MySecondPage})}>
    //   <Text>返回到第二页</Text>
    // </TouchableOpacity>
    // <TouchableOpacity onPress={()=>this.props.navigator.popToTop()}>
    //    <Text>返回到第一页</Text>
    // </TouchableOpacity>
    componentWillUnmount(){
        console.log('MyThirdPage-componentWillUnmount');
    }
    render(){
      return(
        <View style={{marginTop: 60,flex:1,justifyContent: 'center',alignItems: 'center',}}>
            <Text>{'third Page'}</Text>
            <TouchableOpacity onPress={()=>this.props.navigator.replace({component: FirstPage})}>
               <Text>返回到第一页</Text>
            </TouchableOpacity>
        </View>
      )
    }
}

下面是一个查询用户信息的例子,FirstPage传递id到MySecondPage,然后MySecondPage返回user信息给FirstPage。
FirstPage:

import React, { Component } from 'react';
import {
    View,
    Navigator
} from 'react-native'; 
import MySecondPage from './MySecondPage';   

export default class FirstPage extends Component {
    constructor(props) {
        super(props);

        this.state = {
            id: 2,
            user: null,
        }
    }  
    pressButton() {
        if(this.props.navigator) {
            this.props.navigator.push({
                name: 'MySecondPage',
                component: MySecondPage,
                params: {
                    id: this.state.id,
                    //从MySecondPage获取user
                    getUser: (myUser) => {
                        this.setState({
                            user: myUser
                        })
                    }
                }
            });
        }
    }
    render() {
        if(this.state.user) {
            return(
                <View>
                    <Text>用户信息: { JSON.stringify(this.state.user) }</Text>
                </View>
            );
        }else {
            return(
                <View>
                    <TouchableOpacity onPress={this.pressButton.bind(this)}>
                        <Text>查询ID为{ this.state.id }的用户信息</Text>
                    </TouchableOpacity>
                </View>
            );
        }   
    }
}

MySecondPage:

const myObj = {
    1: { name: 'user1', age: 25 },
    2: { name: 'user2', age: 26 }
};
import React from 'react';
import {
    View,
    Navigator
} from 'react-native';
import FirstPage from './FirstPage';

export default class MySecondPage extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            id: null
        }
    }
    componentDidMount() {
        //这里获取从FirstPage传递过来的参数: id
        this.setState({
            id: this.props.id
        });
    }
    pressButton() {
            const { navigator } = this.props;          
            if(this.props.getUser) {
                let user = myObj[this.props.id];
                this.props.getUser(user);
            }             
            if(navigator) {
                navigator.pop();
            }
    }
    render() {
        return(
            <View>
                <Text>获得的参数: id={ this.state.id }</Text>
                <TouchableOpacity onPress={this.pressButton.bind(this)}>
                    <Text>点我跳回去</Text>
                </TouchableOpacity>
            </View>
        );
    }
}

下面是一个登陆页和欢迎页的例子。

MyFirstApp.js:

import React, { Component } from 'react';
import {
  AppRegistry,
  Text,
  View,
  Navigator,
  TouchableOpacity,
  Platform
} from 'react-native';
import Splash from './Splash';

const defaultRoute = {
  component: Splash
};

export default class myFirstApp extends Component {
  _renderScene(route, navigator) {
    let Component = route.component;
    return (
      <Component {...route.params} navigator={navigator} />
    );
  }
  _renderNavBar() {
    const styles = {
      title: {
        flex: 1, alignItems: 'center', justifyContent: 'center'
      },
      button: {
        flex: 1, width: 50, alignItems: 'center', justifyContent: 'center'
      },
      buttonText: {
        fontSize: 18, color: '#FFFFFF', fontWeight: '400'
      }
    }

    var routeMapper = {
      LeftButton(route, navigator, index, navState) {
        if(index > 0) {
          return (
            <TouchableOpacity 
              onPress={() => navigator.pop()}
              style={styles.button}>
              <Text style={styles.buttonText}>Back</Text>
            </TouchableOpacity>
          );
        } else {
          return (
            <TouchableOpacity 
              onPress={() => navigator.pop()}
              style={styles.button}>
              <Text style={styles.buttonText}>Logo</Text>
            </TouchableOpacity>
          );
        }
      },
      RightButton(route, navigator, index, navState) {
        if(index > 0 && route.rightButton) {
          return (
            <TouchableOpacity 
              onPress={() => navigator.pop()}
              style={styles.button}>
              <Text style={styles.buttonText}></Text>
            </TouchableOpacity>
          );
        } else {
          return null
        }
      },
      Title(route, navigator, index, navState) {
        return (
          <View style={styles.title}>
            <Text style={styles.buttonText}>{route.title ? route.title : 'Splash'}</Text>
          </View>
        );
      }
    };

    return (
      <Navigator.NavigationBar
        style={{
          alignItems: 'center',
          backgroundColor: '#55ACEE',
          shadowOffset:{
              width: 1,
              height: 0.5,
          },
          shadowColor: '#55ACEE',
          shadowOpacity: 0.8,          
          }}
        routeMapper={routeMapper} />
    )
  }

  render() {
    return (
        <View style={{height:200}}>
          <Navigator
              initialRoute={defaultRoute}
              renderScene={this._renderScene}
              sceneStyle={{paddingTop: (Platform.OS === 'android' ? 66 : 74)}}
              navigationBar={this._renderNavBar()} />
        </View>
    );
  }
}
});

AppRegistry.registerComponent('myFirstApp', () => myFirstApp);

Splash.js:

import React, { Component } from 'react';
import { View, Text, TouchableOpacity } from 'react-native';

import Login from './Login';

class Splash extends Component {
    _openPage() {
        this.props.navigator.push({
            title: 'Login',
            component: Login
        })
    }
    render() {
        return (
            <View style={{ flex: 1, alignItems: 'center', backgroundColor: '#FFFFFF' }}>
                <Text>Splash Page</Text>

                <TouchableOpacity onPress={this._openPage.bind(this)}>
                    <Text style={{ color: '#55ACEE' }}>Open New Page</Text>
                </TouchableOpacity>
            </View>
        );
    }
}

export default Splash;

Login.js:

import React, { Component } from 'react';
import {View, Text, TextInput, TouchableOpacity } from 'react-native';
import Welcome from './Welcome';

class Login extends Component {
    constructor(props) {
        super(props);
        this.state = {
            name: null,
            age: null,
        }
    }
    _openPage() {
        this.props.navigator.push({
            component: Welcome,
            params: {
                name: this.state.name,
                age: this.state.age,
                changeMyAge: (age) => {
                    this.setState({ age })
                }
            }
        })
    }
    render() {
        return (
            <View style={{ flex: 1, alignItems: 'center', backgroundColor: '#FFFFFF' }}>
                <Text>Form Page</Text>
                <TextInput
                    value={this.state.name}
                    onChangeText={name => this.setState({ name })}
                    placeholder={'Enter your name'}
                    style={{ height: 40, width: 200 }} />
                <Text>My age: {this.state.age ? this.state.age : 'Unknown'}</Text>
                <TouchableOpacity onPress={this._openPage.bind(this)}>
                    <Text style={{ color: '#55ACEE' }}>Update my age</Text>
                </TouchableOpacity>
            </View>
        );
    }
}

export default Login;

Welcome.js:

import React, { Component } from 'react';
import { TextInput, View, Text, TouchableOpacity } from 'react-native';

class Welcome extends Component {
    _back() {
        this.props.navigator.pop();
    }
    render() {
        return (
            <View style={{ flex: 1, alignItems: 'center', backgroundColor: '#FFFFFF' }}>
                <Text>Welcome Page</Text>
                <Text>Welcome to Navigation! {this.props.name}</Text>
                <TextInput
                    onChangeText={age => this.props.changeMyAge(age) }
                    placeholder={'Enter your age:'}
                    style={{ height: 40, width: 200 }} />
                <TouchableOpacity onPress={this._back.bind(this)}>
                    <Text style={{ color: '#55ACEE' }}>Save my age</Text>
                </TouchableOpacity>
            </View>
        );
    }
}
export default Welcome;

12.组件生命周期

实例化
首次实例化

getDefaultProps
getInitialState
componentWillMount
render
componentDidMount

实例化完成后的更新

getInitialState
componentWillMount
render
componentDidMount

存在期
组件已存在时的状态改变

componentWillReceiveProps
shouldComponentUpdate
componentWillUpdate
render
componentDidUpdate

销毁&清理期

componentWillUnmount

说明
生命周期共提供了10个不同的API。
1.getDefaultProps
作用于组件类,只调用一次,返回对象用于设置默认的props,对于引用值,会在实例中共享。
2.getInitialState
作用于组件的实例,在实例创建时调用一次,用于初始化每个实例的state,此时可以访问this.props。
3.componentWillMount
在完成首次渲染之前调用,此时仍可以修改组件的state。
4.render
必选的方法,创建虚拟DOM,该方法具有特殊的规则:
只能通过this.props和this.state访问数据
可以返回null、false或任何React组件
只能出现一个顶级组件(不能返回数组)
不能改变组件的状态
不能修改DOM的输出
5.componentDidMount
真实的DOM被渲染出来后调用,在该方法中可通过this.getDOMNode()访问到真实的DOM元素。此时已可以使用其他类库来操作这个DOM。
在服务端中,该方法不会被调用。
6.componentWillReceiveProps
组件接收到新的props时调用,并将其作为参数nextProps使用,此时可以更改组件props及state。

componentWillReceiveProps: function(nextProps) {
    if (nextProps.bool) {
        this.setState({
            bool: true
        });
    }
}

7.shouldComponentUpdate
组件是否应当渲染新的props或state,返回false表示跳过后续的生命周期方法,通常不需要使用以避免出现bug。在出现应用的瓶颈时,可通过该方法进行适当的优化。
在首次渲染期间或者调用了forceUpdate方法后,该方法不会被调用
8.componentWillUpdate
接收到新的props或者state后,进行渲染之前调用,此时不允许更新props或state。
9.componentDidUpdate
完成渲染新的props或者state后调用,此时可以访问到新的DOM元素。
10.componentWillUnmount
组件被移除之前被调用,可以用于做一些清理工作,在componentDidMount方法中添加的所有任务都需要在该方法中撤销,比如创建的定时器或添加的事件监听器。

import React, { Component, PropTypes } from 'react';
import { Text, View, TouchableOpacity } from 'react-native';

export default class MyPropType extends Component {
    constructor(props){
        super(props);
        this.state = {
            stateName: this.props.myName + ',xhh',
            count: 0,
        }
    console.log('init-constructor');
    }
    static propTypes = {
        myName: PropTypes.string,
        age: PropTypes.number,
        sex: PropTypes.string.isRequired
    }
    static get defaultProps() {
        return {
            myName: "xhh",
            age: 18
        }
    }
    doUpdateCount(){
        this.setState({
            count: this.state.count+1
        })
    }
    componentWillMount() {
      console.log('componentWillMount');
    }
    componentDidMount() {
      console.log('componentDidMount')
    }
    componentWillReceiveProps(nextProps){
      console.log('componentWillReceiveProps')
    }
    shouldComponentUpdate(nextProps, nextState){
        console.log('shouldComponentUpdate');
        // return nextProps.id !== this.props.id;
        if(nextState.count > 10) return false;
        return true;
    }
    componentWillUpdate(){
        console.log('componentWillUpdate');
    }
    componentDidUpdate(){
        console.log('componentDidUpdate');
    }
    componentWillUnmount(){
        console.log('componentWillUnmount');
    }
    render(){
        console.log('render');
        return (
        <View>
            <Text>姓名:{this.props.myName}</Text>
            <Text>别名:{this.state.stateName}</Text>
            <Text>年龄:{this.props.age}</Text>
            <Text>性别:{this.props.sex}</Text>
            <Text>父元素计数是:{this.state.count}</Text>
            <TouchableOpacity onPress={ this.doUpdateCount.bind(this) } style={{ padding: 5,backgroundColor: '#ccc' }}>
                <Text>点我开始计数</Text>
            </TouchableOpacity>
            <SubMyPropType count1={this.state.count} />
        </View>
        )
    }
}
class SubMyPropType extends Component {
    componentWillReceiveProps(nextProps){
      console.log('subMyPropType-componentWillReceiveProps')
    }
    shouldComponentUpdate(nextProps, nextState){
        console.log('subMyPropType-shouldComponentUpdate');
        // return nextProps.id !== this.props.id;
        if(nextProps.count1 > 5) return false;
        return true;
    }
    componentWillUpdate(){
        console.log('subMyPropType-componentWillUpdate');
    }
    componentDidUpdate(){
        console.log('subMyPropType-componentDidUpdate');
    }
    componentWillUnmount(){
        console.log('subMyPropType-componentWillUnmount');
    }
    render(){
        console.log('subMyPropType-render');
        return(
                <Text>子元素计数是:{this.props.count1}</Text>
            ) 
    }
}

// init-constructor
// componentWillMount
// render
// subMyPropType-render
// componentDidMount

//子元素和父元素都在计时
// shouldComponentUpdate
// componentWillUpdate
// render
// subMyPropType-componentWillReceiveProps
// subMyPropType-shouldComponentUpdate
// subMyPropType-componentWillUpdate
// subMyPropType-render
// subMyPropType-componentDidUpdate
// componentDidUpdate

//子元素停止计时(count1 > 5)
// shouldComponentUpdate
// componentWillUpdate
// render
// subMyPropType-componentWillReceiveProps
// subMyPropType-shouldComponentUpdate
// componentDidUpdate

//父元素也停止计时
// shouldComponentUpdate

// 生命周期                 调用次数            能否使用setSate()
// getDefaultProps             1(全局调用一次)       否
// getInitialState             1                     否
// componentWillMount          1                     是
// render                      >=1                   否
// componentDidMount           1                     是
// componentWillReceiveProps   >=0                   是
// shouldComponentUpdate       >=0                   否
// componentWillUpdate         >=0                   否
// componentDidUpdate          >=0                   否
// componentWillUnmount        1                     否 

园中桥
49 声望0 粉丝

愿你眼中总有光芒,活成自己想要的模样。