React是如何渲染元素和组件的

元素的概念

元素是构成 React 应用的最小单位。元素描述了你在屏幕上想看到的内容。React 元素是创建开销极小的普通对象。React DOM 会负责更新 DOM 来与 React 元素保持一致。

将一个元素渲染为 DOM

假设我们的 HTML 文件有一个根元素 <div>该节点内的所有内容都将由 React DOM 管理

js 复制代码
<div id="root"></div>

注意: React 构建的应用通常只有单一的根 DOM 节点,如果你想要将 React 集成进一个已有搭建好的应用,那么你可以在应用中包含任意多的独立根 DOM 节点。

将一个 React 元素渲染到根 DOM 节点中,只需把它们一起传入 ReactDOM.render():

js 复制代码
// 已有的应用
<div> 
<h1>Existing App</h1> 
<div id="root1"></div> 
<div id="root2"></div>
</div>
js 复制代码
import ReactDOM from 'react-dom';
// React 组件
const element1 = <h1>Hello, world</h1>;
const element2 = <h1>Hello, world</h1>;
ReactDOM.render(element1, document.getElementById('root1'));
ReactDOM.render(element2, document.getElementById('root2'));

更新已渲染的元素

React 元素是不可变对象。一旦创建,React 元素的子元素和属性就不能直接更改

时钟组件示例:

js 复制代码
    class Clock extends React.Component {
      constructor(props) {
        super(props);
        this.state = {date: new Date()};
      }

      componentDidMount() {
        this.timerID = setInterval(
        //组件挂载到 DOM 后,每一秒调用一次tick()方法
          () => this.tick(),
          1000
        );
      }

      componentWillUnmount() {
        clearInterval(this.timerID);
      }

      tick() {
        this.setState({
       //使用 `setState` 方法更新组件的状态,将 `date` 属性更新为当前时间的 `Date` 对象 
          date: new Date()
        });
      }

      render() {
        return (
          <div>
            <h1>Hello, world!</h1>
            <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
          </div>
        );
      }
    }

    const root = ReactDOM.createRoot(document.getElementById('root'));
    root.render(<Clock />);

代码分析:

  1. 首先,我们定义了一个名为 Clock 的类,它继承了 React.Component
  2. 在构造函数中,我们初始化了组件的状态(state),其中 date 属性被设置为当前时间的 Date 对象。
  3. 在组件挂载到 DOM 后,componentDidMount 生命周期方法会被调用。在这个方法中,我们创建了一个定时器,并将定时器的 ID 存储在组件的实例变量 timerID 中。定时器每秒触发一次 tick 方法。
  4. tick 方法被调用时,它会使用 setState 方法更新组件的状态,将 date 属性更新为当前时间的 Date 对象。通过调用 setState,React 会检测到状态的变化,并触发重新渲染。
  5. render 方法定义了组件的渲染逻辑。它返回一个包含两个 <h1><h2> 元素的 <div>。其中 <h1> 显示 "Hello, world!",而 <h2> 则显示当前时间,通过访问组件的状态中的 date 属性来获取时间,并使用 toLocaleTimeString 方法将其格式化为本地时间字符串。
  6. 最后,我们使用 ReactDOM.createRoot 创建一个根节点,并将 <Clock /> 组件传递给 root.render 方法,以将组件渲染到指定的根节点上。

这里的生命周期 componentWillUnmount()和 componentDidMount()以及State后面会讲到

注意: 在实践中,大多数 React 应用只会调用一次 ReactDOM.render()。

函数组件与 class 组件

React定义组件的方式主要有两种,函数组件(目前主流)和class组件

函数式组件示例:

复制代码
function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

接收唯一带有数据的 "props"(代表属性)对象与并返回一个 React 元素。这类组件被称为"函数组件"

class组件示例

复制代码
class Welcome extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}

使用自定义组件方式:

复制代码
const element = <Welcome name="zayyo" />;

当 React 元素为用户自定义组件时,它会将 JSX 所接收的属性(attributes)以及子组件(children)转换为单个对象传递给组件,这个对象被称之为 "props"。在上面的示例中name的值"zayyo"就是组件中的的props.name获取到的值。

过程:

  • 我们调用 root.render() 函数,并传入 <Welcome name="zayyo" /> 作为参数。
  • React 调用 Welcome 组件,并将 {name: 'zayyo'} 作为 props 值传入。
  • Welcome 组件将 <h1>Hello, zayyo</h1> 元素作为返回值。
  • React DOM 将 DOM 高效地更新为 <h1>Hello, zayyo</h1>

注意: 组件名称必须以大写字母开头 。因为React 会将以小写字母开头的组件视为原生 DOM 标签。例如,<div /> 代表 HTML 的 div 标签,而 <Welcome /> 则代表一个组件,并且需在作用域内使用 Welcome

组合组件

我们可以使用多个自定义组件来组成我们的页面。

在下面的代码示例中,将会渲染三个 Welcome 组件,分别显示 "Hello, z"、"Hello, A" 和 "Hello, Y":

js 复制代码
    function Welcome(props) {
      return <h1>Hello, {props.name}</h1>;
    }

    function App() {
      return (
        <div>
          <Welcome name="z" />      
          <Welcome name="A" />     
          <Welcome name="Y" />    
         </div>
      );
    }
    ReactDOM.render(<App />, document.getElementById('root'));

在上面,我们使用 <Welcome name="z" /><Welcome name="A" /><Welcome name="Y" /> 分别创建了三个 Welcome 组件的实例,并将它们放置在 <div> 中。

每个 Welcome 组件都会接收不同的 name 属性值,通过 props.name 来访问该属性值,并在组件内部的 <h1> 元素中渲染相应的问候消息。

相关推荐
再学一点就睡5 小时前
前端网络实战手册:15个高频工作场景全解析
前端·网络协议
C_心欲无痕6 小时前
有限状态机在前端中的应用
前端·状态模式
lili-felicity6 小时前
React Native for Harmony 多功能 Avatar 头像组件 完整实现
react native·react.js·智能手机
C_心欲无痕6 小时前
前端基于 IntersectionObserver 更流畅的懒加载实现
前端
candyTong6 小时前
深入解析:AI 智能体(Agent)是如何解决问题的?
前端·agent·ai编程
柳杉6 小时前
建议收藏 | 2026年AI工具封神榜:从Sora到混元3D,生产力彻底爆发
前端·人工智能·后端
weixin_462446236 小时前
使用 Puppeteer 设置 Cookies 并实现自动化分页操作:前端实战教程
运维·前端·自动化
CheungChunChiu6 小时前
Linux 内核动态打印机制详解
android·linux·服务器·前端·ubuntu
Irene19917 小时前
Vue 官方推荐:kebab-case(短横线命名法)
javascript·vue.js
GIS之路7 小时前
GDAL 创建矢量图层的两种方式
前端