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);
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> ) } }
在constructor中初始化state,而后在须要修改时调用setState方法。node
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>
<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', }, });
(1)指定宽高
React Native中的尺寸都是无单位的,表示的是与设备像素密度无关的逻辑像素点。react
<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)宽高android
使用flex:1来指定某个组件扩张以撑满全部剩余的空间。若是有多个并列的子组件使用了flex:1,则这些子组件会平分父容器中剩余的空间。若是这些并列的子组件的flex值不同,则谁的值更大,谁占据剩余空间的比例就更大。
组件可以撑满剩余空间的前提是其父容器的尺寸不为零。若是父容器既没有固定的width和height,也没有设定flex,则父容器的尺寸为零。其子组件若是使用了flex,也是没法显示的。git
<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%的设置,因此若是须要让元素撑满屏幕,须要:github
import { Dimensions, View } from 'react-native'; <View style={{width: Dimensions.get('window').width,height: Dimensions.get('window').height}} />
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
。json
<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>
TextInput
是一个容许用户输入文本的基础组件。它有一个名为onChangeText
的属性,此属性接受一个函数,而此函数会在文本变化时被调用。另外还有一个名为onSubmitEditing
的属性,会在文本被提交后(用户按下软键盘上的提交键)调用(注意react
中的onChange
对应的是rn中的onChangeText
)。react-native
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> ); }
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
了。数组
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> ); } }
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> ); } }
导航方法:
若是你获得了一个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
app
(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;
实例化
首次实例化
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 否