React-Native 生命周期(ES6)

本文详细介绍了React Native中组件的属性(props)和状态(state),强调了它们的区别。重点讲解了组件的生命周期,包括创建阶段(defaultProps、constructor、componentWillMount、render、componentDidMount)、更新阶段(componentWillReceiveProps、shouldComponentUpdate、componentWillUpdate、render、componentDidUpdate)和销毁阶段(componentWillUnmount)。每个阶段的关键方法及其用途进行了阐述,帮助开发者更好地理解和控制组件的生命周期。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在这里插入图片描述

在React Native中使用组件来封装界面模块时,整个界面就是一个大的组件,开发过程就是不断优化和拆分界面组件、构造整个组件树的过程。
所以学习理解组件的生命周期显得尤为重要!
一、组件的属性(props)和状态(state)

属性(props)

它是组件的不可变属性(组件自己不可以自己修改props)。
组件自身定义了一组props作为对外提供的接口,展示一个组件时只需要指定props作为节点的属性。
一般组件很少需要对外公开方法(例外:工具类的静态方法等),唯一的交互途径就是props。所以说它也是父组件与子组件通信的桥梁。
组件自己不可以自己修改props(即:props可认为是只读的),只可由其他组件调用它时在外部修改。

状态(state)

它是组件的内部状态属性,主要用来存储组件自身需要的数据。
除了初始化时可能由props来决定,之后就完全由组件自身去维护。
组件中由系统定义了setState方法,每次调用setState时都会更新组件的状态,触发render方法重新渲染界面。
需要注意的是render方法是被异步调用的,这可以保证同步的多个setState方法只会触发一次render,这样做是有利于提高性能的。
注意:由于 this.props 和 this.state 都用于描述组件的特性,可能会产生混淆。一个简单的区分方法是,this.props 表示那些一旦定义,就不再改变的特性,而 this.state 是会随着用户互动而产生变化的特性。
二、组件的生命周期
对于自定义组件,除了必须实现的render方法,还有一些其他的可选方法可被调用。这些方法会在组件的不同时期之行,所以也可以说这些方法是组件的生命周期方法。
对于组件的生命周期来说一般分为四个阶段,分别为:
创建阶段、实例化阶段、运行(更新)阶段、销毁阶段。

创建阶段

该阶段主要发生在创建组件类的时候,在这个阶段中会初始化组件的属性类型和默认属性。
defaultProps
这里会初始化一些默认的属性,通常会将固定的内容放在这个过程中进行初始化和赋值,一个控件可以利用this.props获取在这里初始化它的属性,由于组件初始化后,再次使用该组件不会调用defaultProps函数,所以组件自己不可以自己修改props(即:props可认为是只读的),只可由其他组件调用它时在外部修改。
在ES6里,可以统一使用static成员来实现.

static defaultProps = {

  autoPlay: false,

  maxLoops: 10,

 };  // 注意这里有分号

static propTypes = {

  autoPlay: PropTypes.bool.isRequired,

  maxLoops: PropTypes.number.isRequired,

  posterFrameSrc:PropTypes.string.isRequired,

  videoSrc: PropTypes.string.isRequired,

  nameString: PropTypes.string.isRequired,

  };  // 注意这里有分号
  1. 实例化阶段

该阶段主要发生在组件类被调用(实例化)的时候。
组件类被实例化的时候,触发一系列流程:
(1) constructor(props)
这里是对控件的一些状态进行初始化,由于该函数不同于defaultProps,在以后的过程中,会再次调用,所以可以将控制控件的状态的一些变量放在这里初始化,如控件上显示的文字,可以通过this.state来获取值,通过this.setState来修改state值。
在ES6里,通过constructor(构造器)对状态进行初始化

 constructor(props){

    super(props);

    this.state = {

        loopsRemaining: this.props.maxLoops,

    };

}

(2) componentWillMount()
准备加载组件
这个调用时机是在组件创建,并初始化了状态之后,在第一次绘制 render() 之前。可以在这里做一些业务初始化操作,也可以设置组件状态。这个函数在整个生命周期中只被调用一次。
如果在这个函数里面调用setState,本次的render函数可以看到更新后的state,并且只渲染一次。
(3) render()
render是一个组件必须有的方法,形式为一个函数,渲染界面,并返回JSX或其他组件来构成DOM,和Android的XML布局、WPF的XAML布局类似,只能返回一个顶级元素。
(4)componentDidMount()
在组件第一次绘制之后,会调用 componentDidMount(),通知组件已经加载完成。这个函数调用的时候,其虚拟 DOM 已经构建完成,你可以在这个函数开始获取其中的元素或者子组件了。需要注意的是,RN 框架是先调用子组件的 componentDidMount(),然后调用父组件的函数。从这个函数开始,就可以和 JS 其他框架交互了,例如设置计时 setTimeout 或者 setInterval,或者发起网络请求。这个函数也是只被调用一次。这个函数之后,就进入了稳定运行状态,等待事件触发。

运行(更新)阶段

该阶段主要发生在用户操作之后,或者父组件有更新的时候,此时会根据用户的操作行为,进行相应的界面结构调整。
触发的流程如下:
(1) componentWillReceiveProps(nextProps)
当组件接收到新的props时,会触发该函数。在该函数中,通常可以调用setState()来完成对state的修改。
输入参数 nextProps 是即将被设置的属性,旧的属性还是可以通过 this.props 来获取。在这个回调函数里面,你可以根据属性的变化,通过调用 this.setState() 来更新你的组件状态,这里调用更新状态是安全的,并不会触发额外的 render() 调用。如下:

componentWillReceiveProps: function(nextProps) {  

  this.setState({

likesIncreasing: nextProps.likeCount > this.props.likeCount

 });

}

(2) shouldComponentUpdate(nextProps, nextState)
返回布尔值(决定是否需要更新组件)
输入参数 nextProps 和上面的 componentWillReceiveProps 函数一样,nextState 表示组件即将更新的状态值。这个函数的返回值决定是否需要更新组件,如果 true 表示需要更新,继续走后面的更新流程。否者,则不更新,直接进入等待状态。
默认情况下,这个函数永远返回 true 用来保证数据变化的时候 UI 能够同步更新。在大型项目中,你可以自己重载这个函数,通过检查变化前后属性和状态,来决定 UI 是否需要更新,能有效提高应用性能。
(3) componentWillUpdate(nextProps, nextState)
shouldComponentUpdate返回true或者调用forceUpdate之后,就会开始准更新组件,并调用 componentWillUpdate()。
输入参数与 shouldComponentUpdate 一样,在这个回调中,可以做一些在更新界面之前要做的事情。需要特别注意的是,在这个函数里面,你就不能使用 this.setState 来修改状态。这个函数调用之后,就会把 nextProps 和 nextState 分别设置到 this.props 和 this.state 中。紧接着这个函数,就会调用 render() 来更新界面了。
(4) render()
再确定需要更新组件时,调用render,根据diff算法,渲染界面,生成需要更新的虚拟DOM数据。
(5) componentDidUpdate()
虚拟DOM同步到DOM中后,执行该方法,可以在这个方法中做DOM操作。
除了首次render之后调用componentDidMount,其它render结束之后都是调用componentDidUpdate。
componentWillMount、componentDidMount和componentWillUpdate、componentDidUpdate可以对应起来。区别在于,前者只有在挂载的时候会被调用;而后者在以后的每次更新渲染之后都会被调用。
注意:绝对不要在componentWillUpdate和componentDidUpdate中调用this.setState方法,否则将导致无限循环调用。

销毁阶段

该阶段主要发生组件销亡的时候,触发componentWillUnmount。当组件需要从DOM中移除的时候,通常需要做一些取消事件绑定,移除虚拟DOM中对应的组件数据结构,销毁一些无效的定时器等工作,都可以在这个方法中处理。
componentWillUnmount()
当组件要被从界面上移除的时候,就会调用 componentWillUnmount。
在这个函数中,可以做一些组件相关的清理工作,例如取消计时器、网络请求等。

总结:
在这里插入图片描述

homeDetail.js

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

export default class HomeDetails extends Component {
    constructor(props) {
        super(props);
        this.state = {}
    }

    componentWillMount() {

    }

    componentWillReceiveProps(nextProps){
        console.log(this.props.detailContent,'this--->>componentWillReceiveProps');
        console.log(nextProps.detailContent,'next--->>componentWillReceiveProps')
    }

    componentDidMount() {

    }

    componentWillUnmount() {

    }

    render() {
        return (
            <View style={styles.container}>
                <Text>欢迎HomeDetails</Text>
            </View>
        )
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        alignItems: "center",
        justifyContent: "center"
    }
});

home.js

import React, {Component} from 'react';
import {
    View,
    Text,
    StyleSheet,
    TouchableOpacity
} from 'react-native';
import {Actions} from 'react-native-router-flux';
import HomeDetails from './HomeDetails';

export default class Home extends Component {
    constructor(props) {
        super(props);
        this.state = {
            clickText: "开始点击按钮",
            count: 1,
            detailContent: true
        }
    }

    componentWillMount() {
        console.log("componentWillMount1111");
    }

    shouldComponentUpdate(nextProps, nextState){
        console.log(this.state.detailContent,'detailContent');
        if (this.state.count !== nextState.count) {
            console.log("shouldComponentUpdate1111---组件需要更新");
            return true;
        }
        return false;
    }

    componentWillUpdate(){
        console.log("componentWillUpdate1111---组件将要更新");
    }

    componentDidUpdate(){
        console.log("componentDidUpdate1111---组件更新完毕");
    }

    componentDidMount() {
        console.log("componentDidMount1111");
    }

    componentWillUnmount() {
        console.log("componentWillUnmount1111");
    }

    clickButton(){
        const { count } = this.state;
        this.setState({
            clickText: "我点击了按钮",
            count: count + 1,
            detailContent: false
        })
    }

    render() {
        console.log("render1111");
        return (
            <View style={styles.container}>
                <Text>欢迎来到首页</Text>
                <TouchableOpacity
                    onPress={() => Actions.notice()}
                >
                    <Text>跳转到公告页</Text>
                </TouchableOpacity>
                <Text style={{color: 'blue', fontSize: 40}}>{this.state.count}</Text>
                <TouchableOpacity
                    style={styles.button}
                    onPress={() => this.clickButton()}
                >
                    <Text>{this.state.clickText}</Text>
                </TouchableOpacity>
                <HomeDetails detailContent={this.state.detailContent}/>
            </View>
        )
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        alignItems: "center",
        justifyContent: "center"
    },
    button: {
        width: 250,
        height: 60,
        backgroundColor: 'red',
        borderRadius: 10,
        alignItems: 'center',
        justifyContent: 'center'
    }
});
### React Native 组件生命周期方法及其调用顺序 React Native 的组件生命周期可以划分为四个主要阶段:创建阶段、实例化阶段、运行(更新)阶段以及销毁阶段。以下是这些阶段中的具体生命周期方法及其调用顺序: #### 1. **创建阶段** 在这个阶段,组件类被定义,静态属性被设置。 - `getDefaultProps` 如果存在,则在此阶段会被调用来设定默认的 props 值[^4]。需要注意的是,在 ES6 类语法中,这个方法已经被废弃,推荐通过直接声明 static 属性来实现相同功能。 #### 2. **实例化阶段** 当组件第一次渲染时会经历此阶段,它包含了以下几个重要的生命周期方法: - `constructor(props)` 构造函数会在组件实例化时执行一次,用于初始化 state 或绑定事件处理程序。这是第一个被执行的方法。 - `static getDerivedStateFromProps(nextProps, prevState)` 此静态方法在首次渲染前和每次重新渲染之前都会被调用,允许我们基于新的 prop 更新状态。 - `componentWillMount` (已废弃) 在首次渲染之前立即调用,但在服务器端渲染期间不会被调用。由于其不可预测的行为,官方建议避免使用该方法,并考虑迁移到其他替代方案。 - `render()` 返回描述 UI 结构的 JSX 元素或 null。它是唯一一个必须实现的方法。 - `componentDidMount()` 当组件已经加载到 DOM 中之后立刻调用。通常在这里发起网络请求或者订阅数据源。 #### 3. **运行(更新)阶段** 每当组件接收到新 Props 或 State 变更时进入此阶段。 - `shouldComponentUpdate(nextProps, nextState)` 默认返回 true;如果希望优化性能可以通过覆盖此方法控制何时需要重绘界面。 - `getSnapshotBeforeUpdate(prevProps, prevState)` 在最近的一次渲染输出提交到 DOM 前调用,可用于捕获一些信息供后续操作使用。 - `componentWillUpdate` (已废弃) 即将在下一版本移除,请改用上述提到的新 API 替代旧版钩子函数。 - `render()` 同上,再次渲染视图结构。 - `componentDidUpdate(prevProps, prevState, snapshot?)` 在组件完成更新后调用,适合做日志记录或其他副作用逻辑。 #### 4. **销毁阶段** 当组件不再需要显示给用户时就会触发卸载过程。 - `componentWillUnmount()` 在组件即将被从 DOM 移除前调用,清理定时器、取消网络请求或是解除事件监听等资源释放工作应该放在这里面进行处理。 ```javascript class MyComponent extends React.Component { constructor(props) { super(props); this.state = { /* 初始化state */ }; } componentDidMount() { console.log('组件挂载'); } shouldComponentUpdate(nextProps, nextState) { return nextProps.someValue !== this.props.someValue || nextState.someOtherValue !== this.state.someOtherValue; } componentDidUpdate(prevProps, prevState) { console.log('组件更新完毕'); } componentWillUnmount() { console.log('组件即将卸载'); } render() { return ( <View> {/* 渲染内容 */} </View> ); } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值