1.一文看懂 react 架构原理
2.react事件机制底层原理
3.React交互原生fetch获取数据
4.React设计原理,源码由浅入深解析 react18 源码(一)
一文看懂 react 架构原理
调和概念指的源码是通过ReactDOM等库实现VDOM(虚拟DOM)与DOM(真实DOM)的同步,即映射VDOM到DOM的源码过程,包括组件的源码挂载、卸载、源码更新等操作,源码jtopo网站源码更新时采用Diff算法对比新旧VDOM树差异。源码
Diff算法的源码核心思想包括三个方面:对比新旧VDOM树的变更,通过跟踪节点的源码增、删、源码改操作来减少真实DOM的源码更新次数,降低性能消耗。源码
React 架构由调和器和渲染器组成,源码其中调和器使用栈调和器,源码其同步更新策略导致当组件树层级过深时,源码公考程序源码更新时间超过浏览器刷新周期,引起交互卡顿。
React 通过引入纤程调和器(fiber reconciler)和调度器优化了架构,通过分片处理更新任务,优先执行高优先级任务,降低视图更新的优先级,从而解决性能问题。更新过程分为reconciliation和commit阶段,分别负责VDOM树的生成和DOM更新。
每个fiber节点与一个React元素对应,通过return、child、sibling属性连接,形成fiber树。自用短线源码页面初始化时,创建fiberRoot和rootFiber,渲染过程中复用当前current树的alternate作为workInProgress树,完成遍历后,以workInProgress树作为新的渲染树,current树作为缓存树,实现双缓冲树结构,避免页面闪烁。
fiber reconciler工作机制包括reconciliation和commit阶段。reconciliation阶段生成fiber树,对比新旧树差异进行更新,commit阶段负责执行DOM更新,通过beforeMutaion、mutation、图片切割工具源码layout等步骤完成视图刷新。
通过优化架构,React 提高了性能,减少了更新时的卡顿,为开发者提供了更高效、更流畅的开发体验。
react事件机制底层原理
阅读须知1.采用react版本为v..2细节可能有所出入,但是原理都是一样的。2.请通过无痕模式调试否则插件容易干扰我们的调试。一、一个demo引发的问题
constApp=()=>{ return<inputonChange={ ()=>{ console.log('这是一个onChang额事件')}}/>}
这是一个平淡无奇的最简单demo,我们看到在input元素绑定onChange事件,当我们定位到这个dom元素的时候发现react为我们添加了input、keydown、DNS系统源码下载blur、change等等事件,而且这些事件都是绑定到document上,并没有绑定到我们的input元素中。那么react究竟做了什么处理呢。
二、react事件是怎么被绑定的首先我们要明白,react中的事件不是原生事件是合成事件,如何合成的呢,我们debugger源码就知道了。当我们打断点调试的时候首先会出来这些东西,首先我们看到这个函数,在react-dom的第一次运行的时候会出现这个。其主要作用初始化一些事件的插件我们拿ChangeEventPlugin来简单的说一下里面主要是用来干什么的吧。
varChangeEventPlugin={ eventTypes:{ change:{ phasedRegistrationNames:{ bubbled:'onChange',captured:'onChangeCapture'},dependencies:[TOP_BLUR,TOP_CHANGE,TOP_CLICK,TOP_FOCUS,TOP_INPUT,TOP_KEY_DOWN,TOP_KEY_UP,TOP_SELECTION_CHANGE]}},_isInputEventSupported:isInputEventSupported,extractEvents:function(topLevelType,targetInst,nativeEvent,nativeEventTarget,eventSystemFlags){ vartargetNode=targetInst?getNodeFromInstance$1(targetInst):window;vargetTargetInstFunc,handleEventFunc;if(shouldUseChangeEvent(targetNode)){ getTargetInstFunc=getTargetInstForChangeEvent;}elseif(isTextInputElement(targetNode)){ if(isInputEventSupported){ getTargetInstFunc=getTargetInstForInputOrChangeEvent;}else{ getTargetInstFunc=getTargetInstForInputEventPolyfill;handleEventFunc=handleEventsForInputEventPolyfill;}}elseif(shouldUseClickEvent(targetNode)){ getTargetInstFunc=getTargetInstForClickEvent;}if(getTargetInstFunc){ varinst=getTargetInstFunc(topLevelType,targetInst);if(inst){ varevent=createAndAccumulateChangeEvent(inst,nativeEvent,nativeEventTarget);returnevent;}}if(handleEventFunc){ handleEventFunc(topLevelType,targetNode,targetInst);}//Whenblurring,setthevalueattributefornumberinputsif(topLevelType===TOP_BLUR){ handleControlledInputBlur(targetNode);}}}其中dependencies属性主要是告诉我们change事件是依赖于它下面的一些事件来合成的。而phasedRegistrationNames是在冒泡或者捕获两个阶段做的一些处理,react会在不同阶段调用不同的处理方法。所以初始化完成之后他们的结构是这样的会形成registrationNameModules与registrationNameDependencies这两个对象如下图所示
形成这两个对象是在diff过程更好的对事件进行处理。
registrationNameModules主要是在diff过程中如果检测到fiber上存在像onClick这些方法就会调用这些插件进行处理。
判断合成事件依赖于那些事件然后调用registrationNameDependencies对应的事件所依赖的原生事件进行绑定。绑定到了document上。
到现在为止我们的react事件绑定完成了并且绑定到了document对象上。
三、react事件如何触发的因为我们在document上绑定了事件,当我们点击的时候肯定知道是哪一个元素触发了这个事件,但是还有一个问题就是我们怎么找到我们在代码写的事件处理函数,因为我们的事件处理函数最后被react初始化到了对应的fiber对象中了所以如何通过dom元素找到其对应的fiber对象,这个就是我们需要探讨的。
这个就是react如何找到对应的fiber对象,是这样的,其中原生dom与其对应的fiber对象中存在一个指向问题,原生dom通过里面一个唯一key指向dom对应的fiber,而fiber中stateNode对应的也是该原生dom对象。所以我们就可以找到了我们写在react中的处理函数。即原生dom->fiber->memoizedProps这里面其实就是冒泡时候先寻找父组件如果父组件有这个事件就加到event._dispatchListeners上,然后遍历这个数组拿到回调然后触发事件为啥用e.preventDefault()?和?returnfalse阻止不了事件,就是这个原因。
好了,我们的react事件绑定机制讲完了,如果有什么意见或者建议请评论告诉我。。
原文:/post/React交互原生fetch获取数据
React交互自由度高,允许使用任何互数据发生交互的库获取数据,本文介绍原生fetch数据方法。
引入React和ReactDOM库:
javascript
import React from 'react';
import ReactDOM from 'react-dom';
创建App组件,初始化状态为空:
javascript
class App extends React.Component{
constructor(){
super();
this.state = {
data: null
};
}
}
定义数据获取方法,使用fetch发起请求,处理响应数据:
javascript
fetchData(){
fetch('url', options).then(response => {
return response.json();
}).then(res => {
this.setState({
data: res
});
}).catch(err => {
console.log('程序发生错误');
});
}
渲染组件时,获取数据:
javascript
render(){
return (
获取数据
);
}
将App组件渲染到页面:
javascript
ReactDOM.render(
,
document.getElementById('root')
);
fetch('url', options).then()接收url和可选参数options,遵循Promise模式处理数据响应。
React设计原理,由浅入深解析 react 源码(一)
React设计原理详解:深入理解React 源码(一)
React的核心工具之一是jsx,它是一种语法扩展,开发者编写的代码会被Babel编译成ReactElement,进一步转化为FiberNode,这是一种虚拟DOM在React中的实现,它能表达组件状态和节点关系,同时具备可扩展性。 FiberNode的工作方式采用深度优先遍历(DFS)策略,递归地处理ReactElement。在渲染过程中,递归分为beginWork(开始工作)和completeWork(完成工作)两个阶段。在ReactDOM的createRoot和render方法中,scheduleUpdateOnFiber和processUpdateQueue负责更新和创建子fiber节点。 在commit阶段,关键步骤包括执行root上的mutation,以及对Host类型的FiberNode构建离屏DOM树。ChildReconciler的两个关键点是子ReactElement到子fiber的创建方式和flag标识的设置。最后,学习者需要注意的是,通过阅读本文,可以关注以下三点:理解jsx与FiberNode的关系
掌握React的递归渲染过程和commit阶段的子阶段
反思和分享你的学习体验,一起探讨React的深入知识
如果你觉得这篇文章有价值,别忘了在留言区分享你的见解,或者将其推荐给你的朋友。让我们一起深化对React 源码的理解。