学习笔记——react的生命周期钩子函数 Love The Way You Lie 2022-12-19 01:22 178阅读 0赞 -------------------- > react的生命周期大体分为三个阶段:组件创建,组件更新,组件销毁。并且只有类组件才具有生命周期的钩子函数,函数组件没有。 ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxMzM5MTI2_size_16_color_FFFFFF_t_70][]**图1.react生命周期钩子函数** ## 1.组件创建: ## > 图1展示了生命周期的钩子函数执行的顺序。 ### 1.constructor(): ### > 可以通过this.state赋值对象来初始化数据。 > > 为事件处理函数绑定实例。 constructor(props) { super(props); this.state = { a: 10, b: 100 }; this.changeName = this.changeName.bind(this); } > 只在组件创建时执行一次,其后不再执行。 ### 2.static getDerivedStateFromProps(): ### > 该函数用来为作为子组件的组件赋初始值,并且该组件可以修改自己state中的数据。 > > 函数内部通常要作判断,如果本组件修改了自身state中的数据,就不需要父组件传来的props中的数据。 > > 在组件创建和更新阶段都会调用。 > > 内无this指针,有两个参数,第一个参数是父组件传来的props中的数据,第二个参数是本组件state中的数据。 > > 必须return一个对象或null。如果是对象,则会合并到本组件的state中去。 static getDerivedStateFromProps(nextProps, prevState) { if(nextProps.b !== prevState.prevProps.b) { return { b: nextProps.b, prevProps: { b: nextProps.b } }; }else return null; } ### 3.componentWillMount() || UNSAFE\_componentWillMount(): ### > 在此函数中调用setState不会触发额外的渲染。但是该功能可以在constructor中直接实现。所以该函数没有什么意义,已经基本处于废弃状态。 ### 4.render(): ### > 渲染页面的主要地方,其中可以实现一些操作,但是必须返回一个jsx对象。 > > 核心代码,会反复调用,减少不必要的render()函数调用次数可以实现性能优化。 render() { // 核心代码,会被反复调用 console.log("render函数运行了"); return ( <div>这是个人中心 <Child b ={this.state.b}></Child> </div> ); } ### 5.componentDIdMount(): ### > 会在组件挂载后调用。组件挂载也就是插入dom树中。 > > 在该函数中,通常会发送ajax请求组件所需要的动态数据。 > > 在这里调用setState会触发render()函数。 componentDidMount() { // 组件挂载完毕 let listMain = await http("/category/list/0"); this.setState({ listMain }); this.changeCategory(listMain[0].id); } ## 2.组件更新: ## > 如何触发组件的更新: > > 1.本组件自身调用setState,会触发re-render(重新渲染)。 > > 2.父组件触发re-render,子组件连带着被re-render。 > > 3.props改变了,会触发本组件re-render。 ### 1.componentWillReceiveProps() || UNSAFE\_componentWillReceiveProps(): ### > 该组件在组件更新时调用,通常用来:当props值发生改变时,在该函数中做相应操作,以响应props值得改变。 > > 该组件已基本被废弃。可以在componentDidUpdate中做相应的操作。 ### 2.static getDerivedStateFromProps(): ### > 与组件创建时一样操作。详情见组件创建。 ### 3.shouldComponentUpdate(): ### > 该函数主要用来对reacr进行性能优化。 > > 该函数必须显示的返回一个true或false。 > > 两个参数,第一个参数为nextProps: 马上要生效的props值,第二个参数为nextState:马上要生效的state值。获取现在的值为this指针。 > > 写出合理的逻辑,减少不必要的更新。如果return false; 就不会向下执行,也就减少了render次数,优化了性能。 shouldComponentUpdate(nextProps){ console.log("child组件的shouldComponentUpdate运行了"); return this.props.b !== nextProps.b; } // 如果不写默认返回true > 进行render优化的代码如下: shouldComponentUpdate(nextProps){ let keys = Object.keys(nextProps); for(let i = 0; i < keys.length; i++) { if(this.props[keys[i]] !== nextProps[keys[i]] ) return true; } return false; } > 就相当于继承自react的pureComponent的类组件默认的shouldComponentUpdate()函数一样。 import React, {PureComponent} from 'react'; class Child extends PureComponent {} > PureComponent比较props中的所有属性,优先决定当前组件是否需要re-render。 > > 但是:PureComponent只做简单的属性值“浅比较”。 > > 浅比较对于值类型还可以,对于引用类型只会比较它们在内存中的地址是否相同,不会进行深层次的比较。 > > 若传过来一个地址不同,内容相同的引用类型,PureComponent无法进行深层次比较。 > > 使用情况:当知道一个组件是类组件,并且这个类组件需要做性能优化。 > 最大的坑:父组件向子组件传引用类型的数据时,不能直接在传值的时候进行绑定。例如: // 错误写法 <Child b ={this.state.b} changeName={this.changeName.bind(this)}></Child> // 正确写法 changeName = () => {}; <Child b ={this.state.b} changeName={this.changeName}></Child> ### 4.componentWillUpdate() || UNSAFE\_componentWillUpdate(): ### > 该方法已被废弃,可以用componentDidUpdate()代替该函数的功能。 > > 如果需要读取dom信息,则可以用getSnapshotBeforeUpdate代替。 componentWillUpdate(){ // 基本废弃,一般不用了。改名了UNSAFE_componentWillUpdate console.log("componentWillUpdate函数运行了"); } ### 5.render(): ### > 更新阶段渲染,可以根据新的数据渲染组件的dom节点。dom节点会与上次相比,找出不一样的节点进行修改。不是全部重新渲染dom节点。 ### 6.getSnapshotBeforeUpdate(): ### > 在该函数中一般执行一些dom操作。记录滚动位置。 > > 例如:可以滚动的页面,突然刷新后,需要在本函数中记录其位置,然后传给componentDidUpdate()函数,可以在更新结束后,重新回到该位置。 > > 有两个参数:prevProps,prevState其内容同上。 > > 需要返回一个值return getSnapshotBeforeUpdate(prevProps, prevState){ return { y: 50 } } componentDidUpdate(prevProps, prevState, snapshot){ console.log(snapshot) // { y: 50 } } ### 7.componentDidUpdate(): ### > 该函数主要在更新完成时执行。 > > 共有两个参数:第一个参数为prevProps,更新前的props值,第二个参数表示更新前的state中的值。当前值为this.props。第三个参数为getSnapshotBeforeUpdate()传过来的数据。 > > 实现类似vue中的watch监听。通过比较更新前和更新后的数据。 > > 这个函数表示最新的state对应的dom更新完毕,所以可以对最新的dom做一些自定义操作。 // 模拟vue中的watch监听 componentDidUpdate(prevProps,prevState) { if(prevState.a !== this.state.a) { console.log("a变量"); } } // 对最新的dom做些自定义操作 // 例如使用插件监听滚动 ### 3.组件销毁: ### > 不再使用,或者长时间不使用的组件需要销毁操作。 ### 1.componentWillUnmount(): ### > 该函数主要用来释放相关的内存空间和资源。 // 组件销毁 componentWillUnmount() { // 释放当前组件相关的内存和资源 console.log("componentWillUnmount运行了") } -------------------- > 以上就是react中的生命周期的钩子函数,通过不同函数可以实现不同的功能。 > > 父组件和子组件中生命周期钩子函数的执行顺序如下: > > 父组件的constructor,render函数比子组件先执行,子组件的componentDidMount,componentDidUpdate比父组件先执行。 [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxMzM5MTI2_size_16_color_FFFFFF_t_70]: /images/20221120/600553d316624897bcaa6dc47ebe19d8.png
还没有评论,来说两句吧...