当前位置: 首页 > article >正文

react18中的函数组件底层渲染原理分析

react 中的函数组件底层渲染原理

  • react组件没有局部与全局之分,它是一个整体。这点跟vue的组件化是不同的。
  • 要实现 react 中的全局组件,可以将组件挂在react上,这样只要引入了react,就可以直接使用该组件。
    在这里插入图片描述

函数式组件的创建

  • 创建一个函数,函数中返回一个jsx或者jsx元素,virtualdom
  • 基于 es6 的模块导入导出方式,将函数作为模块的导出.可以忽略后缀名。
<Component />
<Component>...</Component>
  • 命名:首字母大写,大驼峰命名。小写字母开头,编译器会认为这是一个标签,编译器也会报错。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

关于 props 属性的细节知识

  • 函数组件不能使用this关键字。
  • 函数组件不能使用生命周期钩子。
  • 子组件的props属性,不能直接修改。
  • 获取子组件的props属性,需要使用props.xxx

对象的冻结密封不可扩展

  • 被冻结的对象,不能添加、删除或修改其属性。也不能劫持对象。Object.defineProperty方法不能修改这些属性。Object.isFrozen方法用来检测对象是否被冻结。
  • 被密封的对象的属性,可以修改值,但是不能添加、删除。但不能劫持对象。Object.isSealed方法用来检测对象是否被密封。
  • 不可扩展的对象,除了不能新增成员,其他操作都正常。Object.isExtensible方法用来检测对象是否可以扩展。

总结: 被冻结的对象,既是不可扩展的,也是密封的。被密封的,也是不可扩展的。

所以,我们在组件内部修改props属性时,需要先拷贝一份,然后才能修改。否则会报错。

组件的默认值

  • 函数组件.defaultProps属性,可以设置组件的默认值。
function Jsx({ name }) {
  return (
    <div>
      Jsx
      <hr />
      <p>{name}</p>
    </div>
  );
}

Jsx.defaultProps = { name: "zs22222222" };
export default Jsx;

在这里插入图片描述

函数的类型校验

  • 函数组件.propTypes属性,可以设置组件的默认值。 需要我们安装prop-types库。
    Component组件一样,需要使用import导入。
import PropTypes from "prop-types";
Child.defaultProps = { name: "zs22222222", age: 18 };
Child.propTypes = {
  name: PropTypes.string,
  age: PropTypes.oneOfType([
    PropTypes.number.isRequired,
    PropTypes.string,
    PropTypes.bool,
  ]),
};

函数组件中的插槽处理

  • 插槽的作用,就是将父组件中的内容,原封不动的传递给子组件。想办法让组件更加灵活,具有更强的复用性

    • 数据值用属性

    • html 片段用插槽
      在这里插入图片描述
      在这里插入图片描述

    • children 属性,传递子组件的jsx元素,是数组的情况下,要使用下面的方式来接收,也可以使用React.Children里面的方法来进行处理
      在这里插入图片描述
      在这里插入图片描述

    • 插槽内容可以根据不同的需求,放到不同的位置。
      在这里插入图片描述

静态组件和动态组件

function Vote() {
  function handleSubmit() {}
  function handleCancel() {}
  return (
    <div className="vote-box">
      <div className="header">
        <h2 className="title">标题</h2>
        <span>15</span>
      </div>
      <div className="main">
        <p>支持人数: 10</p>
        <p>反对人数: 5</p>
      </div>
      <div className="footer">
        <button onClick={handleSubmit} className="btn btn-primary">
          支持
        </button>
        <button onClick={handleCancel} className="btn btn-danger">
          反对
        </button>
      </div>
    </div>
  );
}
export default Vote;
  • 第一次渲染组件,执行函数,产生一个私有的上下文,把解析出来的 props 包括 children 属性,保存到上下文,并冻结了props属性,不可修改。返回一个jsx元素的vdom。渲染jsx元素,生成virtualdom

  • 当我们点击按钮,再次渲染组件时
    修改上下文中的变量,私有作用于发生了变化,但是视图不会更新。所以称为静态组件。
    除非在父组件中,修改了子组件的props属性,才会重新渲染。

  • 动态组件:实际项目中,我们会遇到在第一次渲染组件完成后,需要基于组件内部的状态变化,让组件可以更新,以呈现出不同的页面效果。 ====> 动态组件(class 组件,hooks 组件)

  • 2、 初始化状态
    状态:后期修改状态,可以触发视图的更新
    需要手动初始化,如果我们没有去做相关的处理,则默认会往实例上挂载一个state,初始值是null =>this,state=null
    手动处理:

state = {
  xxx:xxx
}

修改状态,控制视图更新this.state.xxx=xxx :这种操作仅仅是修改了状态值,但是无法让视图更新想让视图更新,我们需要基于React.Component.prototype提供的方法操作:「推荐」

  • 1 this.setstate(partialstate)既可以修改状态,也可以让视图更新
  • partialstate:部分状态
 this.setstate({
	xxx:xxx
})
  • 2 this.forceUpdate()强制更新

在这里插入图片描述
在这里插入图片描述
forceUpdate在类组件中生效的使用方法,当你必须使用这个api页面才更新的时候,说明你的业务代码中就已经出现了问题了。如果我们是基于 this.forceUpdate()强制更新视图,会跳过 shouldcomponentUpdate 周期函数的校验,直接从willUpdate开始进行更新,这时视图就一定会更新。

import { Component } from "react";
class Vote extends Component {
  state = {
    oppPerson: 0,
    aggPerson: 0,
  };
  handleSubmit() {}
  handleCancel = () => {
    this.state.oppPerson++;   //这种使用是不对的,
    this.forceUpdate();
  };
  render() {
    const { oppPerson, aggPerson } = this.state;
    return (
      <div className="vote-box">
        <div className="header">
          <h2 className="title">标题</h2>
          <span>15</span>
        </div>
        <div className="main">
          <p>支持人数: {aggPerson}</p>
          <p>反对人数: {oppPerson}</p>
        </div>
        <div className="footer">
          <button onClick={this.handleSubmit} className="btn btn-primary">
            支持
          </button>
          <button onClick={this.handleCancel} className="btn btn-danger">
            反对
          </button>
        </div>
      </div>
    );
  }
}
export default Vote;

请添加图片描述

父子组件的更新顺序

  • vue中
    在这里插入图片描述
  • react中
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

http://www.kler.cn/news/365371.html

相关文章:

  • sharpkeys-键盘部分按键不好用,用其它不常用按键代替
  • 1189.Pell数列
  • C#/.NET/.NET Core全面的自学入门指南
  • 机器学习——元学习(Meta-learning)
  • 鸿蒙到底是不是纯血?到底能不能走向世界?
  • 算法革新决定未来!深挖数字北极星3.0背后的技术逻辑
  • Git的初次使用
  • 若依框架篇-若依集成 X-File-Storage 框架(实现图片上传阿里云 OSS 服务器)、EasyExcel 框架(实现 Excel 数据批量导入功能)
  • Git 完整教程:版本管理、分支操作与远程仓库解析
  • Leetcode|24. 两两交换链表中的节点 ● 19.删除链表的倒数第N个节点 ● 面试题 02.07. 链表相交 ● 142.环形链表II
  • Vue3 项目 npm install 报错 Failed at the node-sass@7.0.3 postinstall script.
  • Python:背景知识及环境安装
  • Servlet(三)-------Cookie和session
  • 【Qt】控件——Qt控件的介绍、QWidget的介绍、QWidget的属性、QWidget的函数
  • 腾讯云技术深度解析:构建高效云原生应用与数据安全管理
  • 开挖 Domain - 前奏
  • 前端零基础入门到上班:【Day5】HTML 和 CSS
  • Qt--利用easyloggingpp库打印日志
  • 3D、VR、AR技术的应用,对家电品牌营销有哪些影响?
  • 强化学习与GPT-o1模型的融合,强化学习对GPT-o1模型思维链能力的影响
  • 使用Python来下一场深夜雪
  • Java面试题四
  • [bug] vllm 0.6.1 RuntimeError: operator torchvision::nms does not exist
  • web网站搭建(静态)
  • 学习webservice的心得
  • 国外LEAD赚美金Voice保号教程