React生命周期

1.什么是生命周期

  • 生命周期就是组件从创建到销毁的过程

  • 生命周期钩子函数:生命周期的每个阶段总是伴随着一些方法的调用,这些方法就叫生命周期的钩子函数,生命周期的钩子函数为我们在不同阶段操作组件提供了时机

  • 只有类组件才有生命周期

2.生命周期三个阶段

  • React组件的生命周期分为三个阶段:创建阶段,更新阶段,卸载阶段

  • 每个阶段常用的钩子函数及触发时机

3.常用的生命周期钩子函数

  • 创建阶段(组件创建时)

    执行顺序:constructor---->render---->componentDidMount

    • constructor

      时机:创建组件时最先执行

      作用:1:初始化state 2:为事件处理程序绑定this

    • render

      时机:每次组件渲染都会触发

      作用:渲染视图(注意:不能调用setState)

    • componentDidMount

      时机:组件挂载(完成DOM渲染后)

      作用:1:发送网络请求 2:DOM操作

代码

import { Component } from "react";

class App extends Component {
constructor() {
  super() // this
  console.log('constructor')
}
render() {
  console.log('render')
  return (
    <div id="app">
      <h1>App组件</h1>
    </div>
  )
}
componentDidMount() {
  console.log('componentDidMount')
}
}
export default App
  • 更新阶段

    使用this.setState更新状态的时候

    组件的props属性发生变化的时候

    强制更新,调用forceupdate()

    执行顺序:render---->componentDidUpdate

    • render

      时机:每次组件渲染都会触发

      作用:渲染视图(注意:不能调用setState)

    • componentDidUpdate

      时机:组件更新完成DOM渲染后

      作用:1:发送网络请求 2:DOM操作

      注意:如果要setState() 必须放在一个if操作中

代码

import { Component } from "react";

class Child extends Component {
  state = {
      count: 0,
  }
  render() {
      console.log('render', 'Child')
      return (
          <div className="app-root">
              <h1>Child组件</h1>
              <button onClick={this.plus}>count+2</button>
              <hr></hr>
              <div>{this.props.num}-----{this.state.count}</div>
          </div>
      )
  }
  componentDidUpdate(prevProps, prevState) {
      // prevProps 更新之前的props的值
      // preState 更新之前的state的值
      // 我们可以对比更新之前的props和state和更新之前的props和state是否一致,来决定是否调用setState
      console.log('componentDidUpdate')
      console.log(prevProps, this.props)
      console.log(prevState, this.state)
  }
  plus = () => {
      this.setState({
          count: this.state.count + 5
      })
  }
}
export default Child
  • 卸载阶段

    • componentWillMount

      时机:组件卸载(从页面中消失)

      作用:执行清理工作(清理定时器以及事件)

父组件

import { Component } from "react";
import Child from "./Child.js";

class App extends Component {
constructor() {
  super() // this
  this.state = {
    num: 10,
    isshow: true,
  }
}
render() {
  return (
    <div id="app">
      <h1>App组件</h1>
      <button onClick={this.toggle}>切换</button>
      {
        this.state.isshow ? <Child num={this.state.num}></Child> : null
      }
      <button onClick={this.add}>更改num</button>
    </div>
  )
}

toggle = () => {
  this.setState({
    isshow: !this.state.isshow
  })
}
add = () => {
  this.setState({
    num: this.state.num + 1
  })
}
}
export default App

子组件

import { Component } from "react";

class Child extends Component {
  state = {
      count: 0,
  }
  render() {
      console.log('render', 'Child')
      return (
          <div className="app-root">
              <h1>Child组件</h1>
              <button onClick={this.plus}>count+2</button>
              <hr></hr>
              <div>{this.props.num}-----{this.state.count}</div>
          </div>
      )
  }
  componentDidUpdate(prevProps, prevState) {
      // prevProps 更新之前的props的值
      // preState 更新之前的state的值
      // 我们可以对比更新之前的props和state和更新之前的props和state是否一致,来决定是否调用setState
      console.log('componentDidUpdate')
      console.log(prevProps, this.props)
      console.log(prevState, this.state)
  }

  componentWillUnmount() {
      console.log('componentWillUnmount')
  }
  plus = () => {
      this.setState({
          count: this.state.count + 5
      })
  }
}
export default Child

4.不常用的生命周期钩子函数

  • static getDerivedStateFromProps

    • getDerivedStateFromProps属于静态方法,所以不能在该方法中访问实例

    • 执行时机:组件创建、更新时

    • 执行顺序:该方法在render方法之前执行

    • 该方法必须返回一个对象来更新state,如果返回null则不更新任何内容

    • static getDerivedStateFromProps(props,state)

App.js

import { Component } from "react";

import List from './List.js'
import FooterCmp from './FooterCmp.js'
class App extends Component {
state = {
  arrList: [
    { id: 1, checked: false, name: 'aaaa' },
    { id: 2, checked: false, name: 'bbbb' },
    { id: 3, checked: false, name: 'cccc' },
    { id: 4, checked: false, name: 'dddd' },
    { id: 5, checked: false, name: 'eeee' },
  ]
}
render() {
  return (
    <div id="app">
      <List arrList={this.state.arrList} handleList={this.handleChange}></List>
      <FooterCmp arrList={this.state.arrList} chooseAll={this.chooseAll}></FooterCmp>
    </div>
  )
}
handleChange = (id) => {
  const copyArrList = [...this.state.arrList]
  const idx = copyArrList.findIndex(item => item.id === id)
  copyArrList[idx].checked = !copyArrList[idx].checked
  this.setState({
    arrList: copyArrList
  })
}

// 全选
chooseAll = (checked) => {
  const copyArrList = [...this.state.arrList]
  copyArrList.forEach(item => {
    item.checked = checked
  })
  this.setState({
    arrList: copyArrList
  })
}
}
export default App

List.js

import { Component } from "react";

class List extends Component {
  render() {
      return (
          <div>
              {this.props.arrList.map(item => (
                  <div key={item.id}>
                      <input type="checkbox" checked={item.checked} onChange={(ev) => (this.handleChange(item.id))} />
                      {item.name}
                  </div>
              ))}
          </div>
      )
  }
  handleChange = (id) => {
      this.props.handleList(id)
  }
}
export default List

FooterCmp.js

import { Component } from "react";

class FooterCmp extends Component {
  state = {
      checked: false
  }
  static getDerivedStateFromProps(nextProps, nextState) {
      // nextProps 下一次的props属性值
      // nextState 下一次的state属性值
      // 当父组件传递过来的arrList数组发生变化时,返回最新的state
      return {
          checked: nextProps.arrList.every(item => item.checked)
      }
  }
  render() {
      return (
          <div>
              全选:
              <input
                  type="checkbox"
                  checked={this.state.checked}
                  onChange={this.changeChecked} />
          </div>
      )
  }
  changeChecked = (ev) => {
      this.props.chooseAll(ev.target.checked)
      // 更改state中checked的值
  }
}
export default FooterCmp
  • shoundComponentUpdate

    • 组件重新渲染前执行

    • 根据shoundComponentUpdate的返回值来决定是否更新自身组件以及子组件,返回true更新,返回false不更新

    • 此方法作为性能优化的一种方案,不能企图依赖该方法来阻止渲染

    • 最好使用React提供的内置组件PureComponent来自动判断是否调用render方法,而不是使用shoundComponentUpdate方法来进行手动判断

    • 不建议在shoundComponentUpdate中进行深层比较或者使用JSOM.stringify

    • shoundComponentUpdate(nextProps, nextState)

      nextProps更新完成后的props的值

      nextState更新完成后的state的值

代码

import { Component } from "react";

class App extends Component {
state = {
  num: 0
}
shouldComponentUpdate(nextProps, nextState) {
  // 判断上一次的state和更新后的state是否相等,来决定是否调用render更新组件
  return nextState !== this.state.num
}
render() {
  console.log('render')
  return (
    <div id="app">
      <button onClick={this.handleClick}>点我</button>
      <h1>父组件</h1>
      <div>{this.state.num}</div>
    </div>
  )
}
handleClick = () => {
  this.setState({
    num: parseInt(Math.random() * 3)
  })
}
}
export default App
 
posted @   杏仁豆腐真君  阅读(40)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
点击右上角即可分享
微信分享提示