说说React render方法的作用原理?

最近使用react的比较多,记录一下一些react的面试题及自己的一些理解和补充,整理成文章更有助于梳理每个知识点的脉络。

Render的形式

在React中,render函数有两种形式:

  1. Class 组件 : 在类组件中,render方法是必需的。这个方法返回一个React元素,描述了组件在特定时间点应该渲染出的内容。例如:

    js 复制代码
    import React, { Component } from 'react';
    
    class MyComponent extends Component {
      render() {
        return <div>Hello, World!</div>;
      }
    }
  2. 函数组件 : 在函数组件中,render函数是函数本身。它接受props作为参数,并返回一个React元素。这个函数被调用时,会根据传入的props和组件内部的逻辑来决定要渲染的内容。例如:

    js 复制代码
    import React from 'react';
    
    function MyComponent(props) {
      return <div>Hello, {props.name}!</div>;
    }

render的原理

创建React元素树

在React应用中,开发者使用JSX语法编写组件的UI结构。当调用render方法时,React会将JSX转换为虚拟DOM(Virtual DOM)元素树

Render主要是把我们编写的jsx通过babel编译后就会转化成我们熟悉的js格式,比如下面这个代码:

javascript 复制代码
return (
  <div className='uname'>
    <Header> hello </Header>
    <div> world </div>
    Hello World
  </div>
)

babel编译后:

kotlin 复制代码
return (
  React.createElement(
    'div',
    {
      className : 'uname'
    },
    React.createElement(
      Header,
      null,
      'hello'
    ),
    React.createElement(
      'div',
      null,
      'world'
    ),
    'hello world'
  )
)

babel对render中的节点转换为虚拟节点,这些虚拟DOM树最终会渲染成真实DOM

比较虚拟DOM

在进行初次渲染或更新时,React会比较前后两次渲染的虚拟DOM树的差异。。React使用一种高效的算法来比较两棵虚拟DOM树的差异,并找出需要更新的部分。一般采用的是diff算法

生成DOM更新操作

js 复制代码
return (
  React.createElement(
    'div',
    {
      className : 'uname'
    },
    React.createElement(
      Header,
      null,
      'hello'
    ),
    React.createElement(
      'div',
      null,
      'world'
    ),
    'hello world'
  )
)

例如,如果新的虚拟DOM树与旧的虚拟DOM树有差异,React可能会生成一些DOM更新操作,如添加、移除或更新DOM元素,而这些操作都是应用在虚拟树上。通过虚拟树上的createElement来创建真实的元素。

应用DOM更新

React会将生成的DOM树更新操作应用到实际的DOM上,以反映最新的UI状态。

例如,如果需要添加新的DOM元素,React会将其添加到DOM树中;如果需要更新现有的DOM元素,则会更新对应的DOM属性和内容;如果需要移除DOM元素,则会将其从DOM树中移除。

React并不会每次调用render方法都直接操作实际的DOM。而是对虚拟树并进行比较和处理,然后再将最终的更新操作应用到实际的DOM上。这种通过虚拟DOM来管理和更新UI的方式,能够提高性能并减少不必要的DOM操作,从而改善用户体验。

总结

render将JSX编写的UI元素转换为虚拟dom树,最终会称为真实的节点,并且虚拟dom树可以通过diff算法来比较虚拟dom,高效的查找到需要更新的元素,通过操作虚拟树而非真实节点的方式来进行新增、更新、移除等操作。

如果觉得有趣或有收获,请关注我的更新,给个喜欢和分享。您的支持是我写作的最大动力!

往期好文推荐

相关推荐
panxianren6 小时前
Bun 1.4 的 bun test --parallel 将 4 秒的测试套件缩短到约 1 秒
java·javascript
码事漫谈8 小时前
骂AI,会让它做得更好吗?
后端
陈随易8 小时前
bm2,Node.js 与 Bun 项目部署新选择
前端·后端·程序员
架构技术专栏9 小时前
AI Agent 框架怎么选:从一次制度查询拆出技术边界
后端·面试
可乐鸡翅yeah_9 小时前
FFmpeg 生成 HLS 独立分片 independent‑segments 参数到底有什么用
javascript·ffmpeg·音视频·safari·m3u8
福兮说9 小时前
canvas 旋转图片的六个坑:四角被裁、Math.ceil 多出 1px 黑边、JPG 角发黑、翻转方向反了
前端·javascript·图像处理·canvas
Ai-_Man11 小时前
您您这可以把Grok的多个会话比如说。左侧的多个会话一次性导出吗?不是单条会话里面的多次会对话。AI导出鸭
javascript·人工智能·ai·小程序·电脑
传人once11 小时前
多图片上传预览功能如何写
前端·css·html·jquery·html5
Eric.4611 小时前
Wan‑Animate+MiniMax-H3 本地部署 AI 漫剧流水线:8G 显存动作迁移与动态分镜工程实战
前端·人工智能·comfyui·ai漫剧
明月_清风11 小时前
SaaS 的三层挣钱逻辑,正在被 AI 从第一层击穿
人工智能·后端