前言
鉴于网上很多有关React生命周期的图解似乎都都不详细,于是近期整理了一下React的生命周期,跟大家分享一下,建议关注收藏,可以时不时回顾一下,如有不对的地方望大家指出,一起学习!
图解
以下是代码和运行过程
父组件 DetailScreen.js
//楼盘详情 created by 轮子弟
import React, {Component} from 'react';
import {
View,
Text,
Button,
StyleSheet,
ScrollView,
ImageBackground,
Image,
TouchableOpacity,
Dimensions,
RefreshControl,
DeviceEventEmitter,
} from 'react-native';
import {connect} from 'react-redux';
import {bindActionCreators} from 'redux';
import * as DetailsActions from '../../../reducers/detailsReducers/DetailsAction';
import store from '../../../configureStore';
import * as api from '../../../networking/Api';
import ConcactInformation from '../../../component/detail/ConcactInformation'; //中介联系方式浮窗
import StatisticsAudience from '../../../component/detail/StatisticsAudience'; //围观人数
import HouseType from '../../../component/detail/HouseType'; //户型
import ItemTitle from '../../../component/detail/ItemTitle'; //自定义标题
import AgentHouse from '../../../component/detail/AgentHouse'; //经纪人楼盘
import MapComponent from '../../../component/detail/MapComponent'; //地图
import ShowPictures from '../../../component/detail/ShowPictures'; //轮播
import TimeAxis from '../../../component/detail/TimeAxis'; //楼盘动态时间轴
const image = {uri: 'https://reactjs.org/logo-og.png'};
// const image = require('./../../resources/cHomeTab/photo/banner.png')
const opening_time = require('./../../../resources/cHomeTab/icon/opening_time.png');
const decoration = require('./../../../resources/cHomeTab/icon/decoration.png');
const developers = require('./../../../resources/cHomeTab/icon/developers.png');
const property_address = require('./../../../resources/cHomeTab/icon/property_address.png');
const sharePhoto = require('./../../../resources/cHomeTab/icon/sharePhoto.png');
// import Banner from './home/component/Swiper_'
const window = Dimensions.get('window');
const screen = Dimensions.get('screen');
class DetailScreen extends Component {
constructor(props, context) {
//Provider是通过context传递给子组件的,子组件通过connect获得数据,实现过程如下,可以看到在没有定义props的情况下,通过context直接取得store中的数据。
// this.store = props.store || context.store
console.log('页面控制器~~~~');
super(...arguments);
this.state = {
refreshing: false,
aa: '窝窝头一块钱四个',
bb: '嗝',
};
}
componentWillMount() {
console.log('页面挂载前~~~~');
}
componentDidMount() {
console.log('页面挂载完成~~~~');
console.log('this.props.banner------', this.props.banner);
this._onRefresh();
// 页面加载完成时注册监听,等DeviceEventEmitter.emit('Refresh')触发后,回到本页面时执行,相当于
this.listener = DeviceEventEmitter.addListener('Refresh', () => {
console.log('有混蛋来了 pao~~~~');
this._onRefresh();
});
setTimeout(() => {
console.log('this.props.banner+++++', this.props.banner);
}, 500);
}
componentWillUpdate() {
console.log('页面准备更新~~~~');
}
componentDidUpdate() {
console.log('页面更新完成~~~~');
}
componentWillUnmount() {
console.log('页面卸载了~~~~');
this.listener.remove();
}
componentWillReceiveProps(nextProps) {
console.log('this.props:', this.props, 'nextProps:', nextProps);
}
// shouldComponentUpdate(newProps, newState) {
// console.log('页面更新拦截钩子~~~~');
// if (newState.a == 'bb') return false;
// return true; //true更新 false阻止更新
// }
_onRefresh = () => {
console.log('this.props.banner', this.props.banner);
console.log('this.props.refreshing', this.props.refreshing);
const houseId = '1790';
// 普通写法(refreshing可以由Store中的中央状态控制,也可以直接setState控制)
// this.setState({refreshing:true})
// DetailsActions.asyncGetHousePhotos(houseId)
// .then((response) => {
// this.setState({refreshing:false})
// if (response.type === 'GetHousePhotos') {
// console.log('response.banner',response.banner);
// this.props.added({type:response.type,banner:response.banner})
// console.log('this.props.banner',this.props.banner);
// this.props.test({a:'01'});
// this.props.test2({a:'02'});
// console.log('this.props.testData',this.props.testData);
// console.log('this.props.testData2',this.props.testData2);
// }
// })
// .catch((error) => {
// return error
// })
// redux-thunk写法(refreshing需要由Store中的中央状态控制)
this.props.toGetHousePhotos(houseId); //刷新轮播
setTimeout(() => {
console.log('更新后this.props.banner', this.props.banner);
console.log('更新后this.props.refreshing', this.props.refreshing);
}, 500);
};
// 点击更新
_goToDetails = () => {
// this.props.navigation.navigate('Map');
console.log('点击测试更新了~~~~');
this.setState({
aa: '嘿嘿',
});
};
render() {
console.log('父页面挂载中~~~~');
return (
<View style={{flex: 1}}>
<ScrollView
style={styles.Scroll}
refreshControl={
<RefreshControl
refreshing={this.props.refreshing}
onRefresh={() => {
this._onRefresh();
}}
/>
}>
<View style={{backgroundColor: '#f5f5f5'}}>
{/* 图片展示 */}
<ShowPictures navigation={this.props.navigation} />
<View style={styles.houseMsg}>
<View style={styles.houseName}>
<Text style={styles.houseTitle}>保利鱼珠港</Text>
<Text style={styles.status}>即将发售</Text>
</View>
<Text style={styles.description}>
珠江中轴之上,位于广州第二CBD最核心区域
</Text>
<View style={styles.label}>
<Text style={styles.SpecificLabel}>专车带看</Text>
<Text style={styles.SpecificLabel}>电梯房</Text>
<Text style={styles.SpecificLabel}>双拼</Text>
<Text style={styles.SpecificLabel}>国际化社区</Text>
</View>
<Text style={styles.price}>36500元/m²</Text>
</View>
<View>
<View>
<View style={styles.projectInformation}>
<View style={styles.informationList}>
<Image source={opening_time} style={styles.icon} />
<View style={styles.listContent}>
<Text style={styles.listText}>开盘时间:</Text>
<Text style={styles.listText}>2018年10月</Text>
</View>
</View>
<View style={styles.informationList}>
<Image source={decoration} style={styles.icon} />
<View style={styles.listContent}>
<Text style={styles.listText}>装修情况:</Text>
<Text style={styles.listText}>带装修</Text>
</View>
</View>
<View style={styles.informationList}>
<Image source={developers} style={styles.icon} />
<View style={styles.listContent}>
<Text style={styles.listText}>开发商:</Text>
<Text style={styles.listText}>保利发展</Text>
</View>
</View>
<View style={styles.informationList}>
<Image source={property_address} style={styles.icon} />
<View style={styles.listContent}>
<Text style={styles.listText}>楼盘地址:</Text>
<Text style={styles.listText}>黄埔黄埔大道动856号</Text>
</View>
</View>
</View>
</View>
<View style={{backgroundColor: '#fff'}}>
<TouchableOpacity
onPress={() => {
this.props.navigation.navigate('ProjectInformation');
}}
activeOpacity={0.5} //触摸时完全不透明,值越小越透明
style={styles.morecontainer}>
<Text style={styles.more}>更多项目信息</Text>
</TouchableOpacity>
</View>
</View>
{/* 围观人数 */}
<StatisticsAudience />
<View style={styles.projectItem}>
<ItemTitle title="项目介绍" />
<Text style={styles.content}>
保利鱼珠港位于黄埔大道东,雄踞广州自西向东发展的珠江东进中轴,接力珠江新城,成为下一个十年重点发展区。2017年政府铭文指出将重点发展第二商务区,保利鱼珠正处于第二CBD的核心区,占领城市规划发汗利好。
</Text>
</View>
<View style={styles.projectItem}>
<ItemTitle
title="热推户型"
seeMore="查看更多"
navigation={this.props.navigation}
/>
{/* 热推户型 */}
<TouchableOpacity
onPress={() => {
// Alert.alert(
// "抱歉!暂还不能使用地图",
// );
this._goToDetails();
}}
activeOpacity={0.9} //触摸时完全不透明,值越小越透明
>
<Text>点击测试子组件更新情况</Text>
</TouchableOpacity>
{/* 子组件1 */}
<HouseType a={this.state.aa'} />
</View>
<View style={styles.projectItem}>
<ItemTitle
title="楼盘动态"
count={24}
seeMore="查看更多"
navigation={this.props.navigation}
/>
{/* 子组件2 */}
<TimeAxis />
</View>
<View style={styles.projectItem}>
<ItemTitle
title="位置周边"
seeMore="查看更多"
navigation={this.props.navigation}
/>
{/* 子组件3 */}
<MapComponent navigation={this.props.navigation} />
</View>
<View style={styles.projectItem}>
<ItemTitle title="经纪人其他楼盘" />
<AgentHouse />
</View>
</View>
</ScrollView>
{/* 中介联系方式 */}
<ConcactInformation />
</View>
);
}
}
export default connect(
(state, ownProps) => {
// console.log('detailState',state)
// console.log('ownProps',ownProps)
return {
userId: state.loginReducer.userId,
banner: state.DetailsReducer.banner,
refreshing: state.DetailsReducer.refreshing,
testData: state.DetailsReducer.testData,
testData2: state.DetailsReducer.testData2,
};
},
(dispatch) => ({
...bindActionCreators(DetailsActions, dispatch),
// 异步操作要写成下面这样才方便
add: (data) => {
console.log('data', data);
dispatch(data);
},
added: (data) => {
console.log('data', data);
dispatch(data);
},
}),
)(DetailScreen);
var styles = StyleSheet.create({
Scroll: {
backgroundColor: '#ffffff',
},
flexLayout: {
flexDirection: 'row',
},
shareIcon: {
position: 'absolute',
top: 10,
right: 30,
width: 40,
height: 40,
},
sharePhotoIcon: {
width: 30,
height: 30,
borderRadius: 14,
},
projectInformation: {
paddingLeft: 15,
backgroundColor: '#ffffff',
paddingBottom: 10,
},
informationList: {
flexDirection: 'row',
alignItems: 'center',
},
listContent: {
flexDirection: 'row',
},
icon: {
marginRight: 5,
},
listText: {
color: '#222222',
fontSize: 16,
lineHeight: 30,
},
morecontainer: {
backgroundColor: '#f5f5f5',
alignItems: 'center',
borderRadius: 3,
overflow: 'hidden',
marginLeft: 15,
marginRight: 15,
},
more: {
lineHeight: 45,
fontSize: 17,
color: '#495b84',
},
houseMsg: {
paddingLeft: 15,
paddingRight: 15,
backgroundColor: '#ffffff',
paddingTop: 20,
},
houseName: {
flexDirection: 'row',
alignItems: 'center',
},
houseTitle: {
color: '#222222',
fontSize: 20,
lineHeight: 25,
marginRight: 10,
},
status: {
height: 25,
lineHeight: 25,
backgroundColor: '#fae5e4',
color: '#ec736f',
borderRadius: 5,
overflow: 'hidden',
paddingLeft: 5,
paddingRight: 5,
fontSize: 13,
},
description: {
height: 25,
lineHeight: 25,
color: '#545454',
},
label: {
flexDirection: 'row',
},
SpecificLabel: {
height: 20,
lineHeight: 20,
fontSize: 13,
color: '#495b84',
backgroundColor: '#f5f5f5',
paddingLeft: 5,
paddingRight: 5,
borderRadius: 3,
overflow: 'hidden',
marginRight: 10,
},
price: {
fontSize: 25,
color: '#eb5e36',
lineHeight: 50,
},
projectItem: {
paddingLeft: 15,
paddingRight: 15,
backgroundColor: '#ffffff',
marginTop: 10,
paddingTop: 20,
paddingBottom: 20,
},
content: {
color: '#545454',
fontSize: 16,
lineHeight: 22,
},
});
子组件1 HouseType
import React, {Component} from 'react';
import {
TouchableOpacity,
Image,
StyleSheet,
View,
Text,
ScrollView,
} from 'react-native';
const huxing = require('./../../resources/cHomeTab/photo/huxing.png');
import Test from './test';
export default class HouseType extends Component {
static defaultProps = {};
constructor(props) {
console.log('子页面1控制器~~~~');
super(props);
this.state = {};
}
componentWillMount() {
console.log('子页面1挂载前~~~~');
}
componentDidMount() {
console.log('子页面1挂载完成~~~~');
}
componentWillUpdate() {
console.log('子页面1准备更新~~~~');
}
componentDidUpdate() {
console.log('子页面1更新完成~~~~');
}
componentWillUnmount() {
console.log('子页面1已销毁~~~~');
}
componentWillReceiveProps(value) {
console.log('子页面1有属性了~~~~', value);
}
shouldComponentUpdate(newProps, newState) {
console.log('子组件1更新拦截钩子shouldComponentUpdate~~~~');
if (newProps.a == '嘿嘿') return true;
return false; //true更新 false阻止更新
}
render() {
console.log('子页面1挂载中~~~~');
return (
<ScrollView showsHorizontalScrollIndicator={false} horizontal={true}>
<Test />
<TouchableOpacity
onPress={() => {}}
activeOpacity={0.5} //触摸时完全不透明,值越小越透明
style={[
styles.flexLayout,
{
justifyContent: 'space-between',
alignItems: 'center',
marginRight: 50,
},
]}>
<Image source={huxing} style={styles.HouseType} />
<View style={styles.HouseTypeInfo}>
<View style={styles.flexLayout}>
<Text style={[styles.HouseTypeText, {marginRight: 10}]}>
2房1厅1厨1卫
</Text>
<Text style={styles.HouseTypeText}>164m²</Text>
<Text style={styles.HouseTypeText}>{this.props.a}</Text>
</View>
<Text style={styles.briefIntroduction}>
户型精巧布局,南北通透,多向采光,享受多阳光清风
</Text>
</View>
</TouchableOpacity>
<TouchableOpacity
onPress={() => {}}
activeOpacity={0.5} //触摸时完全不透明,值越小越透明
style={[
styles.flexLayout,
{
justifyContent: 'space-between',
alignItems: 'center',
marginRight: 50,
},
]}>
<Image source={huxing} style={styles.HouseType} />
<View style={styles.HouseTypeInfo}>
<View style={styles.flexLayout}>
<Text style={[styles.HouseTypeText, {marginRight: 10}]}>
2房1厅1厨1卫
</Text>
<Text style={styles.HouseTypeText}>164m²</Text>
</View>
<Text style={styles.briefIntroduction}>
户型精巧布局,南北通透,多向采光,享受多阳光清风
</Text>
</View>
</TouchableOpacity>
<TouchableOpacity
onPress={() => {}}
activeOpacity={0.5} //触摸时完全不透明,值越小越透明
style={[
styles.flexLayout,
{
justifyContent: 'space-between',
alignItems: 'center',
marginRight: 50,
},
]}>
<Image source={huxing} style={styles.HouseType} />
<View style={styles.HouseTypeInfo}>
<View style={styles.flexLayout}>
<Text style={[styles.HouseTypeText, {marginRight: 10}]}>
2房1厅1厨1卫
</Text>
<Text style={styles.HouseTypeText}>164m²</Text>
</View>
<Text style={styles.briefIntroduction}>
户型精巧布局,南北通透,多向采光,享受多阳光清风
</Text>
</View>
</TouchableOpacity>
</ScrollView>
);
}
}
const styles = StyleSheet.create({
flexLayout: {
flexDirection: 'row',
},
HouseType: {
width: 80,
height: 70,
},
HouseTypeInfo: {
width: 285,
paddingLeft: 20,
},
HouseTypeText: {
fontSize: 16,
lineHeight: 30,
},
briefIntroduction: {
color: '#545454',
fontSize: 17,
lineHeight: 25,
},
});
子组件2 TimeAxis
import React, {Component} from 'react';
import {StyleSheet, View, Text} from 'react-native';
import {connect} from 'react-redux';
import * as api from '../../networking/Api';
class TimeAxis extends Component {
static defaultProps = {};
constructor(props) {
console.log('子页面2控制器~~~~');
super(props);
this.state = {
invoice: [
{
id: 1,
ctime: '2020年01月30日',
content: '星河丹堤新春购房优惠5重豪礼,购房最高直减72万',
contentDetails:
'星河丹堤主力在售D区澜山组团130-139m四五房半山观海揽湖洋房以及219- 235m联排...',
},
{
id: 2,
ctime: '2020年01月01日',
content: '星河丹堤唯一半山臻品南向小户型49-77m盛大发售',
contentDetails:
'星河丹堤2020年1月1日加推南沙唯一半山臻品小洋房,类公寓设计,2梯9户13层高, 首二...',
},
{
id: 3,
ctime: '2019年10月01日',
content: '南沙星河丹堤压轴洋房新品D3栋小高层国庆发售',
contentDetails:
'星河丹堤压轴洋房新品--澜山组团D区洋房 首页范区于10月1日全球盛放,同步认购。推售产...',
},
{
id: 3,
ctime: '2019年10月01日',
content: '南沙星河丹堤压轴洋房新品D3栋小高层国庆发售',
contentDetails:
'星河丹堤压轴洋房新品--澜山组团D区洋房 首页范区于10月1日全球盛放,同步认购。推售产...',
},
{
id: 3,
ctime: '2019年10月01日',
content: '南沙星河丹堤压轴洋房新品D3栋小高层国庆发售',
contentDetails:
'星河丹堤压轴洋房新品--澜山组团D区洋房 首页范区于10月1日全球盛放,同步认购。推售产...',
},
{
id: 3,
ctime: '2019年10月01日',
content: '南沙星河丹堤压轴洋房新品D3栋小高层国庆发售',
contentDetails:
'星河丹堤压轴洋房新品--澜山组团D区洋房 首页范区于10月1日全球盛放,同步认购。推售产...',
},
{
id: 3,
ctime: '2019年10月01日',
content: '南沙星河丹堤压轴洋房新品D3栋小高层国庆发售',
contentDetails:
'星河丹堤压轴洋房新品--澜山组团D区洋房 首页范区于10月1日全球盛放,同步认购。推售产...',
},
{
id: 3,
ctime: '2019年10月01日',
content: '南沙星河丹堤压轴洋房新品D3栋小高层国庆发售',
contentDetails:
'星河丹堤压轴洋房新品--澜山组团D区洋房 首页范区于10月1日全球盛放,同步认购。推售产...',
},
{
id: 3,
ctime: '2019年10月01日',
content: '南沙星河丹堤压轴洋房新品D3栋小高层国庆发售',
contentDetails:
'星河丹堤压轴洋房新品--澜山组团D区洋房 首页范区于10月1日全球盛放,同步认购。推售产...',
},
],
};
}
componentWillMount() {
console.log('子页面2挂载前~~~~');
}
componentDidMount() {
console.log('子页面2挂载完成后~~~~');
console.log('userId...', this.props.userId);
// toTo楼盘动态
const houseid = 1790;
api
.GetHouseDynamics(houseid)
.then((res) => {
// console.log('GetHouseDynamics',res.items)
// this.setState({
// bannerData:res.result.items
// })
})
.catch((error) => {
// console.log('data',error)
});
}
componentWillUpdate() {
console.log('子页面2准备更新~~~~');
}
componentDidUpdate() {
console.log('子页面2更新完成~~~~');
}
componentWillUnmount() {
console.log('子页面2已销毁~~~~');
}
render() {
console.log('子页面2挂载中~~~~');
console.log('this.props.banner', this.props.banner);
console.log('this.props.refreshing', this.props.refreshing);
const TimeItem = this.state.invoice.slice(0, 3).map((item, index) => {
return (
<View style={styles.expressItem} key={index}>
<View style={styles.expressRightFirst}>
<View>
<Text style={{color: '#202020', fontSize: 18, lineHeight: 50}}>
{item.ctime}
</Text>
<Text style={{color: '#202020', fontSize: 18, lineHeight: 35}}>
{item.content}
</Text>
<Text style={{color: '#888888', fontSize: 18, fontWeight: '500'}}>
{item.contentDetails}
</Text>
</View>
</View>
{index == 0 ? (
<View style={styles.expressLeftContainer}>
<View style={styles.expressLeftFirst}></View>
<View style={styles.expressLeft}></View>
</View>
) : (
<View style={styles.expressLeftContainer}>
<View style={[styles.expressLeft]}></View>
</View>
)}
</View>
);
});
return <View style={styles.content}>{TimeItem}</View>;
}
}
export default connect(
(state) => {
return {
userId: state.loginReducer.userId,
banner: state.DetailsReducer.banner,
refreshing: state.DetailsReducer.refreshing,
// userName: state.loginReducer.userName,
// password: state.loginReducer.password,
};
},
(dispatch) => ({
// ...bindActionCreators(LoginActions, dispatch),
// setAppInfo: (data) => dispatch(setAppInfo(data)),
}),
)(TimeAxis);
const styles = StyleSheet.create({
expressRightFirst: {
paddingLeft: 25,
},
content: {
borderLeftWidth: 1,
borderLeftColor: '#e0e0e0',
},
expressItem: {
flexDirection: 'row',
paddingBottom: 20,
},
expressLeft: {
width: 10,
height: 10,
borderRadius: 5,
backgroundColor: '#e0e0e0',
position: 'absolute',
left: 5,
top: 5,
},
expressLeftFirst: {
width: 10,
height: 20,
backgroundColor: '#fff',
position: 'absolute',
left: 5,
top: -20,
},
expressLeftContainer: {
width: 20,
height: 20,
borderRadius: 10,
backgroundColor: '#ffffff',
position: 'absolute',
left: -10,
top: 15,
},
});
子组件3 MapComponent
import React, {Component} from 'react';
import {
TouchableOpacity,
Image,
StyleSheet,
View,
Text,
ScrollView,
Alert,
} from 'react-native';
const map = require('./../../resources/cHomeTab/photo/map.png');
const metro = require('./../../resources/cHomeTab/icon/metro.png');
const transit = require('./../../resources/cHomeTab/icon/transit.png');
const Restaurant = require('./../../resources/cHomeTab/icon/Restaurant.png');
const school = require('./../../resources/cHomeTab/icon/School.png');
const hospital = require('./../../resources/cHomeTab/icon/hospital.png');
const shopping = require('./../../resources/cHomeTab/icon/shopping.png');
import {unitWidth, unitHeight, height} from '../../../js/common/ScreenUtil';
// const map = require('./../../resources/cHomeTab/photo/map.png')
// const tipsIcon = require('./../../resources/cHomeTab/icon/tipsIcon.png')
export default class MapComponent extends Component {
static defaultProps = {};
constructor(props) {
console.log('子页面3控制器~~~~');
super();
this.state = {
// 地图选项内容
tab: [
{
metroUrl: metro,
metroText: '地铁',
},
{
metroUrl: transit,
metroText: '公交',
},
{
metroUrl: Restaurant,
metroText: '餐饮',
},
{
metroUrl: school,
metroText: '学校',
},
{
metroUrl: hospital,
metroText: '医院',
},
{
metroUrl: shopping,
metroText: '购物',
},
],
};
}
componentWillMount() {
console.log('子页面3挂载前~~~~');
}
componentDidMount() {
console.log('子页面3挂载后~~~~');
}
componentWillUpdate() {
console.log('子页面3准备更新~~~~');
}
componentDidUpdate() {
console.log('子页面3更新完成~~~~');
}
componentWillUnmount() {
console.log('子页面3已销毁~~~~');
}
// 点击跳转查看地图
_goToDetails = () => {
// this.props.navigation.navigate('Map');
this.setState({
tab: [
{
metroUrl: metro,
metroText: '地铁2',
},
{
metroUrl: transit,
metroText: '公交2',
},
{
metroUrl: Restaurant,
metroText: '餐饮2',
},
{
metroUrl: school,
metroText: '学校2',
},
{
metroUrl: hospital,
metroText: '医院2',
},
{
metroUrl: shopping,
metroText: '购物2',
},
],
});
};
render() {
console.log('子页面3挂载中~~~~');
return (
<View style={styles.mapItem}>
<TouchableOpacity
onPress={() => {
// Alert.alert(
// "抱歉!暂还不能使用地图",
// );
this._goToDetails();
}}
activeOpacity={0.9} //触摸时完全不透明,值越小越透明
>
<View style={{flexDirection: 'row'}}>
<Image
resizeMode="cover"
style={{height: 382 * unitWidth, width: '100%'}}
source={map}
/>
</View>
<View
style={{
flexDirection: 'row',
justifyContent: 'space-between',
paddingLeft: 40 * unitWidth,
paddingRight: 40 * unitWidth,
marginTop: 22 * unitWidth,
}}>
{this.state.tab.map((item, index) => (
<View style={{alignItems: 'center'}} key={index}>
<Image
resizeMode="cover"
style={{height: 40 * unitWidth, width: 40 * unitWidth}}
source={item.metroUrl}
/>
<Text style={[styles.itemTitle, {color: '#000'}]}>
{item.metroText}
</Text>
</View>
))}
</View>
</TouchableOpacity>
</View>
);
}
}
const styles = StyleSheet.create({
mapItem: {
// flexDirection:'row',
// justifyContent:'space-between'
},
itemTitle: {
fontSize: 15,
lineHeight: 40,
},
address: {
color: '#888888',
fontSize: 12,
lineHeight: 25,
},
unitPrice: {
color: '#eb5e36',
fontSize: 17,
},
});
打印结果
初始化阶段
可以看出父组件先发起初始化,执行render时,优先依次挂载完成子组件后,父组件最后才挂载完成,可以理解成两个阶段,一个是发起挂载动作(由父到子,同级组件得先等上一个同级等的子组件都发起挂载动作了才轮到),另一个是结束挂载动作(由子到父,同级组件得等上一个组件挂载完成了才能轮到,依次进行)
有一点需要注意的是初始化阶段render时componentWillReceiveProps不执行
运行中
可以看出父组件先发起更新,执行render时,优先依次更新完成子组件后,父组件最后才更新完成,可以理解成两个阶段,一个是发起挂载动作(由父到子,同级组件得先等上一个同级等的子组件都发起更新动作了才能轮到),另一个是结束更新动作(由子到父,同级组件得等上一个组件更新完成了才能轮到,依次进行)
当子组件1HouseType将shouldComponentUpdate中的返回值变为以下后,再点击后,子组件1将通过return false来定向阻止更新,自然后面的componentWillUnmount和componentWillReceiveProps也不会再继续执行了
shouldComponentUpdate(newProps, newState) {
console.log('子组件1更新拦截钩子shouldComponentUpdate~~~~');
if (newProps.a == '嘿嘿') return false;
return true; //true更新 false阻止更新
}
此时打印结果是:
可见子组件1执行到shouldComponentUpdate钩子后便停止了!
销毁阶段
可以看出父组件先销毁,再依次销毁子组件,同级子组件得先等前面等子组件都销毁完了才销毁结束
执行次数
只执行一次: constructor、componentWillMount、componentDidMount
执行多次:render 、子组件的componentWillReceiveProps、componentWillUpdate、componentDidUpdate
有条件的执行:componentWillUnmount(页面离开,组件销毁时) 不执行的:根组件(ReactDOM.render在DOM上的组件)的componentWillReceiveProps(因为压根没有父组件给传递props)