React18 07 React中的Class类组件

React中的继承原理

// 1.首先基于call继承, React.Component.call(this) //this为parent类的实例p
class Parent extends React.Component{
    constructor(props){
        super(props)
        this.props =props; //如果这里没有设置任何的逻辑,则报错
    }
    x=100;   //私有属性
    getX(){}  //根据上面的案例,可以知道这样的写法就是会在Parent.protoType中找到这个函数咯~
    // 打印后会发现P中除了这些信息,还有多余的几个属性或方法,是React.Component中封装好的,源码为
    // function Component(props,context,updater) {
    //     this.props = props;
    //     this.context = context;
    //     this.refs = emptyObject;
    //     this.updater = updater||ReactNoopUpdateQUeue;
    // }
    
}
2.再基于原型链继承Parent.prototype.__proto__===React.Component.prototype
// 从实例->Parent.prototype->React.Component.prototype->Object.prototype
// 实例除了具备Parent.prototype提供的方法之外,还具备了React.Component.prototype原型上提供的方法
// 3.只要设置了constructor,则内部一定要写super(),且写在最前面
let p = new Parent(100); //props参数
console.log(p)

封装类组件实现状态与视图的更新
1. 初始化属性与规则校验
(1)方案1:
Constructor(props){
super(props) //会把传递进来的属性挂载到this实例上
}
(2)方案2:
即便不在constructor中处理,或者不写constructor,在constructor处理完毕后,React内部也会把传递的props挂载到实例上,所以在其他的函数中,只要保证this是实例,就可以基于this.props获取传递的属性,但是获取到的属性对象是被冻结的。
直接在render函数中打印this.props也可以看到被传递的数据
2. 初始化状态
状态:后期修改状态,可以触发视图的更新
需要手动初始化,如果不做相关处理,则会默认往实例上挂载一个state,初始值是null=>> this.state=null

注:vue中直接修改状态值,视图自己会更新,原理是对状态做了数据劫持,修改值的时候,会触发set劫持函数,在这个函数中,会通知视图更新,但React不行,React只修改了状态,但是视图不会更新~ 必须使用setState,或者forceUpdate

import React from "react";
import PropTypes from "prop-types";
class ClassFun2 extends React.Component {
  static defualtProps = {
    title: "暂无标题",
  };
  static propTypes = {
    title: PropTypes.string.isRequired,
  };
  // 初始化状态
  state = {
    supportNum: 10,
    opposeNum: 20,
  };
  render() {
    let { title } = this.props,
      { supportNum, opposeNum } = this.state;
    return (
      <>
        <h2 className="title">{title}</h2>
        <div>总人数:{supportNum + opposeNum}</div>
        <div>支持的人数:{supportNum}</div>
        <div>反对的人数:{opposeNum}</div>
        <br />
        <button
          onClick={() => {
            this.state.supportNum++;
            this.forceUpdate();//控制台会预警 Do not mutate state directly. Use setState()
          }}
        >
          我支持
        </button>
        <button
          onClick={() => {
            this.setState({
                opposeNum:opposeNum+1
            })
          }}
        >
          我反对
        </button>
      </>
    );
  }
}

export default ClassFun2;

3.执行相关的周期函数:ComponentWillMount:第一次渲染之前
该周期函数目前是不安全的,可以使用但是未来可能被删除,不建议使用。一定要使用的话可以在前面加 UNSAFE_
但是在严格模式下,控制台依旧是会预警的~

 UNSAFE_componentWillMount(){
    console.log('componentWillMount:最先执行')
  }


4. 触发render周期函数进行渲染
5. 触发componentDidMount:第一次渲染完毕,virtualDOM=》真实DOM了~

componentDidMount(){
    console.log('componentDidMount:第一次渲染完毕')
  }

类组件更新的底层逻辑
1.触发shouldComponentUpdate(),是否允许更新
return true允许后才触发setSate(),false不允许则不会继续往下执行,但forceUpdate会跳过这个步骤

shouldComponentUpdate(){
    console.log('shouldComponentUpdate:是否允许更新')
    return false;
}

2.触发componentWillUpdate(),更新之前,也是不安全的函数,目前还能使用
3.修改状态值属性,让this.state.xxx改为最新的值
4.触发render函数,组件更新
按照最新的状态属性,把返回的JSX编译为virtualDOM,和第一次渲染出来的virtualDOM进行对比【DOM-DIFF】,把差异的部分进行渲染,渲染为真实的DOM
5.触发componentDidMount(),更新完毕
6.触发componentWillUnmount,组件卸载

除了子组件修改更新视图,父组件的更新也可以让子组件更新~


Hooks组件 推荐使用:具备了函数组件和类组件的各自优势,在函数组件的基础上,基于hooks函数,让函数组价也可以拥有状态,周期函数等,让函数组件也可以实现自更新动态化~

posted @ 2025-03-10 18:00  JocelynFung  阅读(71)  评论(0)    收藏  举报
Live2D 看板娘 / Demo