react 执行过程

简介: 【10月更文挑战第27天】React的执行过程是一个复杂而有序的过程,通过各个阶段的生命周期方法、虚拟DOM的渲染和更新、事件处理以及状态管理等机制,实现了高效、灵活的组件化开发模式,使得开发者能够构建出高性能、可维护的前端应用。

React的执行过程:

组件初始化

  • 创建React元素:React应用的起点通常是通过 React.createElement() 函数创建React元素。这个函数接受三个参数:元素的类型(可以是HTML标签名、自定义组件名或 React.Fragment 等特殊类型)、元素的属性对象以及子元素。例如,const element = React.createElement('div', { className: 'container' }, 'Hello, React!'); 创建了一个简单的 div 元素。
  • 渲染React元素:创建好React元素后,需要将其渲染到页面上的某个DOM节点中。通过 ReactDOM.render() 函数来实现,它接受两个参数:要渲染的React元素和目标DOM节点。例如,ReactDOM.render(element, document.getElementById('root')); 会将上述创建的 div 元素渲染到 idroot 的DOM节点中。

组件挂载

  • 创建组件实例:当渲染一个自定义组件时,React会首先创建该组件的实例。对于类组件,会调用组件的构造函数,并传入 props。在构造函数中,通常会初始化组件的状态 state。对于函数组件,每次渲染都会执行函数组件本身,它接收 props 作为参数,并返回一个React元素。
  • 挂载生命周期方法:对于类组件,在组件实例创建后,React会依次调用 getDerivedStateFromProps() 方法和 componentWillMount() 方法(在React 17中已被标记为不安全的生命周期方法,不建议使用)。getDerivedStateFromProps() 用于根据新的 props 来更新组件的状态,它是一个静态方法,接收当前的 propsstate 作为参数,并返回一个新的状态对象或 nullcomponentWillMount() 方法在组件挂载之前被调用,通常用于一些初始化操作,但由于其可能会导致一些难以预测的副作用,在新的React版本中已逐渐被废弃。
  • 渲染组件:在完成生命周期方法的调用后,组件会执行 render() 方法来生成虚拟DOM树。render() 方法必须返回一个有效的React元素或 null。对于类组件,它返回的是通过 React.createElement() 或其他方式创建的React元素;对于函数组件,它直接返回一个React元素。这个虚拟DOM树描述了组件的UI结构和内容。
  • 创建真实DOM节点:React会根据虚拟DOM树创建相应的真实DOM节点,并将其插入到页面中的目标DOM节点中。在这个过程中,React会对虚拟DOM树进行 diff 算法的比较,只更新需要改变的部分,以提高性能。同时,React会为每个真实DOM节点添加一些必要的属性和事件处理函数,以便与组件的状态和交互逻辑进行关联。
  • 执行 componentDidMount():在组件挂载到页面后,React会调用 componentDidMount() 方法。这个方法通常用于执行一些需要在组件挂载后立即执行的操作,如发起网络请求、订阅事件监听器等。由于此时组件已经渲染到页面上,因此可以安全地访问和操作DOM节点。

组件更新

  • 触发更新:组件的更新可以由多种原因触发,如 props 的改变、组件内部状态的改变、父组件的重新渲染等。当这些情况发生时,React会重新执行组件的更新过程。
  • 更新生命周期方法:对于类组件,首先会调用 getDerivedStateFromProps() 方法,根据新的 props 来更新组件的状态。然后,如果组件使用了 shouldComponentUpdate() 方法,React会调用该方法来判断组件是否需要重新渲染。如果 shouldComponentUpdate() 返回 true,则继续执行后续的更新过程;如果返回 false,则跳过本次更新,直接使用之前的渲染结果。接着,React会调用 componentWillUpdate() 方法(同样在React 17中已被标记为不安全的生命周期方法,不建议使用),在组件更新之前执行一些准备工作。
  • 重新渲染组件:与挂载阶段类似,组件会再次执行 render() 方法来生成新的虚拟DOM树。然后,React会使用 diff 算法将新的虚拟DOM树与旧的虚拟DOM树进行比较,找出需要更新的部分,并对真实DOM节点进行相应的更新操作。这个过程只更新发生变化的DOM节点,而不是重新渲染整个组件树,从而提高了更新的效率。
  • 执行 componentDidUpdate():在组件更新完成后,React会调用 componentDidUpdate() 方法。这个方法接收前一个 propsstate 作为参数,可以用于在组件更新后执行一些操作,如根据新的状态更新DOM节点的样式、发起新的网络请求等。需要注意的是,在 componentDidUpdate() 中访问 this.propsthis.state 时,应该使用当前的 propsstate,而不是前一个 propsstate

组件卸载

  • 执行 componentWillUnmount():当组件从页面中移除时,React会调用 componentWillUnmount() 方法。这个方法通常用于执行一些清理操作,如取消网络请求、移除事件监听器、清理定时器等。在这个方法中,应该释放所有与组件相关的资源,以避免内存泄漏和其他潜在的问题。
  • 移除真实DOM节点:在 componentWillUnmount() 方法执行完成后,React会将与组件对应的真实DOM节点从页面中移除,释放相关的DOM资源。

事件处理

  • 事件绑定:在React中,事件处理函数通常是在组件的 render() 方法中通过 onClickonChange 等属性绑定到DOM节点上的。React会对这些事件进行代理,将所有的事件绑定到根节点上,然后根据事件的冒泡机制来触发相应的事件处理函数。这样做的好处是可以提高性能,减少内存占用,并且可以在不同的浏览器中保持一致的事件行为。
  • 合成事件:React使用合成事件来处理DOM事件。合成事件是对原生DOM事件的封装,它提供了一个跨浏览器兼容的事件对象,并且在事件处理函数中自动绑定了 this 指针,使得开发者可以更方便地编写事件处理逻辑。例如,在一个按钮的点击事件处理函数中,可以直接通过 this.propsthis.state 来访问组件的属性和状态,而不需要手动绑定 this
  • 事件冒泡和捕获:React的事件系统遵循DOM事件的冒泡和捕获机制。开发者可以通过在事件处理函数中使用 event.stopPropagation() 来阻止事件的冒泡,或者使用 event.preventDefault() 来阻止默认的事件行为。这样可以根据具体的业务需求来控制事件的传播和处理。

状态管理

  • 状态初始化:在类组件中,状态通常是在构造函数中通过 this.state 来初始化的。状态是一个对象,包含了组件的各种数据,这些数据会影响组件的渲染结果。例如,一个计数器组件可能有一个 count 状态,用于记录当前的计数。
  • 状态更新:当需要更新组件的状态时,应该使用 this.setState() 方法。this.setState() 会异步地更新组件的状态,并触发组件的重新渲染。在更新状态时,可以传递一个对象作为参数,该对象包含了需要更新的状态属性和新的值。React会自动将新的状态与旧的状态进行合并,并重新渲染组件。例如,对于上述的计数器组件,可以通过 this.setState({ count: this.state.count + 1 }); 来增加计数。
  • 状态的不可变性:在React中,状态应该被视为不可变的。这意味着不应该直接修改 this.state 对象,而是应该通过 this.setState() 方法来创建一个新的状态对象。这样做的好处是可以提高性能,并且便于进行状态的比较和更新。同时,遵循状态的不可变性原则也有助于提高代码的可维护性和可预测性。

React的执行过程是一个复杂而有序的过程,通过各个阶段的生命周期方法、虚拟DOM的渲染和更新、事件处理以及状态管理等机制,实现了高效、灵活的组件化开发模式,使得开发者能够构建出高性能、可维护的前端应用。

相关文章
|
7月前
|
Web App开发 前端开发 JavaScript
React 之 requestAnimationFrame 执行机制探索
React 之 requestAnimationFrame 执行机制探索
256 0
|
24天前
|
前端开发 调度 UED
React 执行过程中 Fiber 的优先级是如何确定的?
【10月更文挑战第27天】React能够更加智能地管理任务的执行顺序,在保证用户交互体验的同时,充分利用系统资源,提高应用的整体性能和响应速度。
|
25天前
|
前端开发 JavaScript 算法
React的运行时
【10月更文挑战第25天】React的运行时通过虚拟DOM、组件渲染、状态管理、事件系统以及协调与更新等机制的协同工作,为开发者提供了一种高效、灵活的方式来构建用户界面和处理交互逻辑。这些机制相互配合,使得React应用能够快速响应用户操作,同时保持良好的性能和可维护性。
|
2月前
|
JavaScript 前端开发
使用 React 和 Redux 构建一个计数器应用
【10月更文挑战第3天】使用 React 和 Redux 构建一个计数器应用
|
4月前
|
前端开发
React 中的 Hook 概念
【8月更文挑战第31天】
36 0
|
7月前
|
前端开发 算法
React中的setState执行机制?
React中的setState执行机制?
|
7月前
|
前端开发 JavaScript 算法
react中的setState的执行机制
react中的setState的执行机制
43 0
|
前端开发
react解决死循环方法?
react解决死循环方法?
|
前端开发 JavaScript
React中的setState的执行机制
React中的setState的执行机制
106 0
|
前端开发 API 开发者
React18中useEffect执行两次
React18中useEffect执行两次
1247 3