【react】react18的学习(二)-三种组件

上篇:【react】react18的学习(一)-基本配置
本篇内容:函数组件、插槽实现、类组件

六、组件

1、函数组件(静态组件,没有this)

命名:大驼峰;
传props值:同普通标签,除字符串,用{}形式传递;
接收props值:
渲染:

  • 同样,跟元素一起,先由babel-preset-react-app将标签转为React.createElement()
  • 机制:函数组件标签为函数类型,与普通标签不同,React.createElement()处理函数标签,先执行将props传入函数,然后执行函数,生成虚拟DOM;
  • 再将虚拟DOM传给root.render(),渲染成真实DOM;

props 介绍
+ 在组件被解析成虚拟DOM后,标签上的属性和子标签就被放在虚拟DOM对象的props里了;
+ props对象被冻结,只读;
+ 用于父子传值;
+ 校验功能:import PropTypes from 'prop-types'
+ 插槽功能: let { children } = props

// 插槽
import React from 'react';
let { children } = props 
// 默认children可能为数组[](传多标签)、对象{}(传单标签)、字符串""(传值)
// 使用React.Children,不会改变props中的children
children = React.Children.toArray(children)
console.log(children);//转为数组
// 具名插槽如下图

在这里插入图片描述

在这里插入图片描述

// views/Demo.jsx
// package.json中配置自动引入
// import React from 'react';
import PropTypes from 'prop-types'
// props 初始值
Demo.defaultProps = {
  age: 10
}
// props 校验
Demo.propTypes = {
  title: PropTypes.string.isRequired,
  age: PropTypes.number
}
export default function Demo(props) {
  console.log(props);
  let { title, age, style, children } = props
  age = 19
  return (
    <div style={style}>
    	年龄:{age},标题:{title}
    	{children}
   	</div>
  );
}
---------------------------------------------------------------------------------
// 入口文件:index.jsx
import Demo from './views/Demo'
root.render(
  <Demo title={'aa'} age={18} style={{ color: 'red' }}>
      <span>123</span>
      <span>456</span>
  </Demo>
)
// babel解析
React.createElement(
  Demo, 
  {
  	age: 10,
  	style: {
    	color: "red"
  	}
  }
);
// React.createElement()执行,生成虚拟DOM
{
    $$typeof:Symbol(react.element)
    key:null,
    ref:null,
    type: f Demo(),
    props:{
        age:10;
        style:{
            color:"red"
        }
    },
    ...
}

2、类组件(动态组件,有生命周期等,当作构造函数,new创建类实例执行)

extends继承

1、通过React.Component.call(this),给实例赋私有属性:props、refs、context、updater

2、将类的原型对象的原型链指向:Parent.prototype.__proto__ == Reaact.Component.prototype,这样实例可以沿着原型链访问;

首次渲染过程:
  • getDefaultProps:初始化属性、进行属性校验、执行render
  • getInitialState:初始化状态 state,在实例上挂载,默认null(没有双向绑定,没有响应式set,状态更改不会自动更新视图,需要使用官方组件原型上的方法:this.setState()、this.state + this.forceUpdate()
  • 生命周期1:UNSAFE_componentWillMount
  • 生命周期2:render函数,触发子组件渲染,返回虚拟Dom,并开始渲染(不是root.render()方法,这个方法没有返回值,是入口文件用于触发组件)
  • 生命周期3:componentDidMount,可以获取真实Dom
组件更新

方式一:组件state触发更新

  • 生命周期4:shouldComponentUpdate(nextProps, nextState, nextContext),通过强制更新组件直接跳过该周期函数;
  • 生命周期5:UNSAFE_componentWillUpdate(nextProps, nextState, nextContext)
  • 生命周期2:render,就是最初写的,触发子组件更新渲染
  • 生命周期6:componentDidUpdate(preProps, preState, snapshot)

方式二:父组件重新渲染,从而更新子组件

  • 生命周期7:UNSAFE_componentWillReceiveProps(nextProps, nextContext)

最后一个生命周期8: componentWillUnmount:父组件销毁,先销毁子组件;

生命周期
类组件的首次渲染
getDefaultProps:初始化属性
getInitialState:初始化状态
UNSAFE_componentWillMount:挂载前
render:渲染生成虚拟DOM
componentDidMount:挂载后,可获取真实DOM
// 类组件的更新
shouldComponentUpdate:是否更新
UNSAFE_componentWillUpdate:更新前
render:渲染生成虚拟DOM
componentDidUpdate:更新后
UNSAFE_componentWillReceiveProps:父组件触发子组件更新
componentWillUnmount:销毁前
PureComponent与Component

shouldComponentUpdate:是否更新

  • Pure:会在这个周期函数时对props和state实现了一个浅层次的比较(对象中子项是否都一样),如果有任何props或state发生了更改,则返回true;
  • 后者默认返回true;
  • 浅比较
    在这里插入图片描述
类组件的 refs

受控组件:通过修改状态更新视图
非受控组件:通过获取真实DOM更新视图;

原生元素真实DOM:三种方式

可在生命周期 componentDidMount(){}、componentDidUpdate(preProps,preState)()

  • ref 为字符串(官方不推荐)
<div ref='vote'>
----
this.refs.[ref名]
  • ref 为函数(推荐)
<div ref={x => this.box = x}>
---
this.box
  • ref 为 Ref对象(推荐)
// 生成Ref对象
box = React.createRef()
// 类原型上的方法(类原型上加属性只能用prototype)
render() {
  return (
    <div ref={this.box}>
----
this.box.current

组件标签上的 ref:

// 类组件:获取实例
<Demo1 ref={x => this.child1 = x} />
// 函数组件:获取某个元素
<Demo2 ref={x => this.child2 = x} />
----
const Demo2 = React.forwardRef((props, ref) => {
  return (
    <div ref={ref}></div>
  );
})

3、Hooks组件(融合两种组件优势)

函数组件:渲染块,机制简单,静态组件;

类组件:功能强大,渲染慢,动态组件;

hooks组件:对函数组件的改造;

下一篇:【react】react18的学习(三)-hooks组件

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值