专业编程基础技术教程

网站首页 > 基础教程 正文

react高质量笔记_8(组件的生命周期)

ccvgpt 2024-08-15 20:27:54 基础教程 12 ℃

一、组件的生命周期

1. 理解

1、组件从创建到死亡它会经历一些特定的阶段。

2、React组件中包含一系列钩子函数(生命周期回调函数), 会在特定的时刻调用。

react高质量笔记_8(组件的生命周期)

3、我们在定义组件时,会在特定的生命周期回调函数中,做特定的工作。

4、(名称、叫法)生命周期回调函数<=> 生命周期钩子函数<=>生命周期函数<=>生命周期钩子

5、挂载 mount: 组件第一次被渲染到DOM中的时候,叫挂载 ReactDOM.render(<Life/>, document.querySelector('test'))

6、卸载 unmount:组件被删除时,在react中被称为卸载 ReactDOM.unmountComponentAtNode(document.querySelector('test'))

2. 生命周期流程图(旧)

3. 生命周期的三个阶段(旧)

1. 初始化阶段: 由ReactDOM.render()触发---初次渲染

(1) constructor():构造函数

(2) componentWillMount():组件即将挂载

(3) render():渲染到页面

(4) componentDidMount():组件挂载完毕 常用一般在这个钩子中做一些初始化的事,例如:开启定时器、发送网络请求、订阅消息

2. 更新阶段: 由组件内部this.setSate()或父组件render触发

(1) shouldComponentUpdate():组件更新

(2) componentWillUpdate():组件即将更新

(3) render() =====> 必须使用的一个

(4) componentDidUpdate():组件更新完毕

3. 卸载组件: 由ReactDOM.unmountComponentAtNode()触发

(1) componentWillUnmount():组件即将卸载,常用,一般在这个钩子中做一些收尾的事,例如:关闭定时器、取消订阅消息

4. 生命周期流程线路

l线路1(初始化页面时)

constructor构造器 =》componentWillMount(组件即将挂载)=》render(挂载)=》componentDidMount(组件挂载完成)=》componentWillUnmount(组件将要卸载)

<script type="text/babel">
   class Count extends React.Component{
     //构造器
     constructor(props) {
       console.log("Count===构造器constructor执行")
       super(props);
       //初始化数据
       this.state={
       	count:0
       }
     }
   //函数点我加1
   add = ()=>{
     const {count} = this.state
     this.setState({count:count+1})
   }

   //函数卸载组件
   death = ()=>{
  	 ReactDOM.unmountComponentAtNode(document.getElementById("test"))
   }
   //函数强制更新
   force = ()=>{
   	this.forceUpdate()
   }
   //==============生命周期钩子函数===============
   //组件即将挂载
   componentWillMount(){
   	console.log('count====componentWillMount组件即将挂载钩子函数执行')
   }

   //组件挂载完毕
   componentDidMount(){
   	console.log('count====componentDidMount组件挂载完成钩子函数执行')
   }
   //组件将要卸载
   componentWillUnmount(){
   	console.log('count====componentWillUnmount组件卸载钩子函数执行')
   }

   render() {
     console.log("Count===render组件执行")
     const {count} = this.state
     return (
       <div>
         <h2>当前求和为:{count}</h2>
         <button onClick={this.add}>点我+1</button>
         <button onClick={this.death}>卸载组件</button>
         <button onClick={this.force}>不更改任何状态中的数据,强制更新一下</button>
       </div>
       );
     }
   }
   ReactDOM.render(<Count/>, document.getElementById('test'))
</script>

点击卸载组件

l 线路2(数据进行更新)

setState()修改数据 =》shouldComponentUpdate(组件更新)=》componentWillUpdate(组件将要更新)=》render(组件渲染)=》componentDidUpdate(组件更新完成)

<script type="text/babel">
   class Count extends React.Component{
     //构造器
     constructor(props) {
       console.log("Count===构造器constructor执行")
       super(props);
       //初始化数据
       this.state={
       	count:0
       }
     }
     //函数点我加1
     add = ()=>{
       console.log('add函数执行')
       const {count} = this.state
       this.setState({count:count+1})
     }

     //函数卸载组件
     death = ()=>{
     	ReactDOM.unmountComponentAtNode(document.getElementById("test"))
     }
     //函数强制更新
     force = ()=>{
     	this.forceUpdate()
     }
     //==============生命周期钩子函数===============
     //组件即将挂载
     componentWillMount(){
     	console.log('count====componentWillMount组件即将挂载钩子函数执行')
     }

     //组件挂载完毕
     componentDidMount(){
     	console.log('count====componentDidMount组件挂载完成钩子函数执行')
     }
     //组件将要卸载
     componentWillUnmount(){
     	console.log('count====componentWillUnmount组件卸载钩子函数执行')
     }

     //=================更新数据============
     //更新组件 返回boole值
     shouldComponentUpdate(){
       console.log('count====shouldComponentUpdate组件更新钩子函数执行')
       //如果返回false,后面的更新操作将不在执行
       return true
     }
     //组件即将更新
     componentWillUpdate(){
     	console.log('count====componentWillUpdate组件即将更新钩子函数执行')
     }
     //组件更新完成
     componentDidUpdate(){
     	console.log('count====componentDidUpdate组件更新完成钩子函数执行')
     }


     render() {
       console.log("Count===render组件执行")
       const {count} = this.state
       return (
         <div>
           <h2>当前求和为:{count}</h2>
           <button onClick={this.add}>点我+1</button>
           <button onClick={this.death}>卸载组件</button>
           <button onClick={this.force}>不更改任何状态中的数据,强制更新一下</button>
         </div>
       );
     }
   }
   ReactDOM.render(<Count/>, document.getElementById('test'))
</script>

l 线路3(强制更新)

forceUpdate()强制更新 =》componentWillUpdate(组件将要更新)=》render(组件渲染)=》componentDidUpdate(组件更新完成)

l 线路4(父子组件数据传递)

父组件render() =》componentWillReceiveProps(子组件:组件将要接收props参数)=》shouldComponentUpdate(子组件:组件更新)=》componentWillUpdate(子组件:组件即将更新)=》componentDidUpdate(子组件:组件更新完成)

<script type="text/babel">
   class A extends React.Component{
     state = {
     	carName:'奔驰'
     }

     changeCar = ()=>{
     	this.setState({carName:'宝马'})
     }
     render() {
       console.log("A===render组件执行")
       return (
         <div>
           <div>我是A组件</div>
           <button onClick={this.changeCar}>换车</button>
           <B carName={this.state.carName}/>
         </div>
       	);
       }
     }

     class B extends React.Component{
       //组件将要接收新的props的钩子函数
       componentWillReceiveProps(props){
       	console.log("B===componentWillReceiveProps组件执行",props)
       }
       //组件更新
       shouldComponentUpdate(){
         console.log("B===shouldComponentUpdate组件执行")
         return true
       }
       //组件即将更新
       componentWillUpdate(){
       	console.log("B===componentWillUpdate组件执行")
       }
       //组件更新完成
       componentDidUpdate(){
       	console.log("B===componentDidUpdate组件执行")
       }

       render() {
       console.log("B===render组件执行")
       return (
         <div>
          <div>我是B组件,接收到的车是:{this.props.carName}</div>
         </div>
       );
      }
   }

   ReactDOM.render(<A/>, document.getElementById('test'))
</script>

注意:

shouldComponentUpdate返回值必须为true或false,若不写,默认为true

forceUpdate():强制更新。不更改任何状态中的数据,强制更新一下

5. 生命周期流程图(新)

17及以上版本

6. 生命周期的三个阶段(新)

1. 初始化阶段: 由ReactDOM.render()触发---初次渲染

(1) constructor()

(2) getDerivedStateFromProps:从props中获取状态

(3) render()

(4) componentDidMount() => 常用,一般在这个钩子中做一些初始化的事,例如:开启定时器、发送网络请求、订阅消息

2. 更新阶段: 由组件内部this.setSate()或父组件重新render触发

(1) getDerivedStateFromProps

(2) shouldComponentUpdate()

(3) render()

(4) getSnapshotBeforeUpdate 在更新之前获取快照,返回值传递给

(5) componentDidUpdate()

3. 卸载组件: 由ReactDOM.unmountComponentAtNode()触发

(1) componentWillUnmount() => 常用,一般在这个钩子中做一些收尾的事,

例如:关闭定时器、取消订阅消息

<script type="text/babel">
   class Count extends React.Component{
     //构造器
     constructor(props) {
       console.log("Count===构造器constructor执行")
       super(props);
       //初始化数据
       this.state={
       	count:0
       }
     }
     //函数点我加1
     add = ()=>{
       console.log('add函数执行')
       const {count} = this.state
       this.setState({count:count+1})
     }

     //函数卸载组件
     death = ()=>{
     	ReactDOM.unmountComponentAtNode(document.getElementById("test"))
     }
     //函数强制更新
     force = ()=>{
       console.log("count====force函数执行")
       this.forceUpdate()
     }
     //==============生命周期钩子函数===============
     //若state的值在任何时候都取决于props,那么可以使用getDerivedStateFromProps
     static getDerivedStateFromProps(props, state){
       console.log('count====getDerivedStateFromProps 钩子函数执行',props, state)
       return null
     }

     //组件挂载完毕
     componentDidMount(){
    	 console.log('count====componentDidMount组件挂载完成钩子函数执行')
     }
     //组件将要卸载
     componentWillUnmount(){
     	console.log('count====componentWillUnmount组件卸载钩子函数执行')
     }

     //=================更新数据============
     //更新组件 返回boole值
     shouldComponentUpdate(){
       console.log('count====shouldComponentUpdate组件更新钩子函数执行')
       //如果返回false,后面的更新操作将不在执行
       return true
     }

     //更新组件之前获取快照
     getSnapshotBeforeUpdate(){
       console.log('count====getSnapshotBeforeUpdate 钩子函数执行')
       return false
     }
     //组件更新完成
     componentDidUpdate(preProps,preState,snapshotValue){
     	console.log('count====componentDidUpdate组件更新完成钩子函数执行',preProps,preState,snapshotValue)
     }


     render() {
       console.log("Count===render组件执行")
       const {count} = this.state
       return (
         <div>
           <h2>当前求和为:{count}</h2>
           <button onClick={this.add}>点我+1</button>
           <button onClick={this.death}>卸载组件</button>
           <button onClick={this.force}>不更改任何状态中的数据,强制更新一下</button>
         </div>
       );
     }
   }
   ReactDOM.render(<Count/>, document.getElementById('test'))
</script>

? 初始化

? 更新数据页面

? 强制更新

? 卸载组件

注意:

1、17及以上版本componentWillMount、componentWillUpdate、componentWillReceiveProps三个钩子使用前要加UNSAFE_前缀才能使用,以后可能会被彻底废弃,不建议使用。

2、新的生命周期和旧的生命周期相比,除了即将废弃三个钩子,还添加了两个新的钩子getDerivedStateFromProps和getSnapshotBeforeUpdate

3、static getDerivedStateFromProps:适用于罕见用例(几乎不用),返回null或state对象,state的值在任何时候都取决于props

4、getSnapshotBeforeUpdate(prevProps,prevState,):在更新之前获取快照,返回值传递给componentDidUpdate(prevProps,prevState,snapshotValue)

7. getSnapShotBeforeUpdate的使用场景

保留更新之前的原始数据

<script type="text/babel">
   class NewsList extends React.Component{
     //构造器
     state = {
     	newArr:[]
     }

     //组件挂载完成
     componentDidMount(){
       //开启定时任务 每一秒钟增加一条新闻
       setInterval(()=>{
         const {newArr} = this.state
         const news = "新闻"+newArr.length
         this.setState({newArr:[news, ...newArr]})
       },1000)
     }
     //更新组件之前获取快照
     getSnapshotBeforeUpdate(){
       //需求:定位到中间为止不动
       //获取数据高度
       console.log(this.refs.list.scrollHeight)
       return this.refs.list.scrollHeight
     }
     //组件更新完成
     componentDidUpdate(preProps,preState,snapshotValue){
       //完成定位
       this.refs.list.scrollTop += this.refs.list.scrollHeight - snapshotValue
     }
     render() {
       const {newArr} = this.state
       return (
         <div>
           <div className="list" ref="list">
             {
               newArr.map((item,index)=>{
               	return <div key={index} className="news">{item}</div>
               })
             }
           </div>
         </div>
    	 );
     }
   }
   ReactDOM.render(<NewsList/>, document.getElementById('test'))
</script>
<style>
   .list{
     width: 200px;
     height: 200px;
     background-color: skyblue;
     overflow: auto;
   }
   .news{
   	height: 30px;
   }
</style>

结语:

 努力了这么久,但凡有点儿天赋,也该有些成功的迹象了

回复react笔记,可以获得全套笔记

react高质量笔记_7(组件三大核心属性之refs)

react高质量笔记_6(组件三大核心属性之props)

最近发表
标签列表