-
Vue2响应式原理
- 数据劫持
- 创建Observer 监听data中的数据
- 递归遍历对象属性
- 依赖收集储存(组件渲染时,触发getter方法)
- 创建Watcher观察数据的变化,存储到Dep订阅列表中
- 触发更新(触发setter)
- 调用notify方法,通知Watcher进行更新
- 数据劫持
-
Vue3 响应式原理
-
创建响应式对象,即创建Proxy对象拦截原始对象的访问和修改
-
依赖收集
-
组件渲染时会创建ReactiveEffect 类
ReactiveEffect初始化时会访问响应式对象的属性,触发get拦截器并添加Dep依赖中
-
调用track函数收集依赖
track函数会将当前的ReactiveEffect实例添加到目标对象的依赖集合中
-
-
触发更新
-
触发Set拦截器,调用trigger函数,通过所有依赖更新
-
-
-
React响应式原理
-
初始渲染
- 生成组件实例,解析jsx,创建Fiber树(每个组件实例对应一个Fiber节点,包括属性、类型、状态)
- 调用render方法生成虚拟dom
- 根据虚拟dom构建Fiber树
- 根据虚拟dom构建实际dom节点并插入到页面
- 调用生命周期方法useEffect
-
状态或属性变化
- 状态State、Prop变化、useEffect依赖变化
-
调度更新
- 将状态变化调度到更新队列中
-
重新渲染
- 通过render方法生成新的虚拟DOM
-
协调
- 通过diff算法对比新旧虚拟DOM,生成最小的DOM操作列表
-
更新
- 通过DOM操作列表更新到实际DOM
-
生命周期
-
组件更新前后执行对应的生命周期钩子
-
-
-
vue和react区别
- vue的响应式原理通过proxy(defineProperty)自主监听更新,react的响应式原理则是通过setState手动触发
-
react 常用钩子
- useState
- useEffect(组件渲染后异步执行,无阻塞)、useLayoutEffect(组件渲染前同步调用,修改dom场景)
- useCallback(用于优化缓存函数)、useMemo(用于优化缓存组件或计算结果)
- useContext (全局上下文 用于隔代组件传参)
- useRecuder(类型Redux reducer 处理多种场景)
- useRef (绑定组件 接收子组件方法或数据)useImperativeHandle(暴露子组件的方法或数据)
- useTransition (用于更新切换 过度状态)
- useSyncExternalStore(用于订阅外部数据源,如Redux Store)
-
react17变更
- 全新jsx转换(不再使用creatElement调用,而是自动从React的package包入口函数引入并调用)
- 事件委托变更 (不再将事件添加在
document
上,而是添加到渲染 React 树的根 DOM 容器中) - 事件系统更改(onScroll不再冒泡)
- 副作用清理(同步改为异步 减少副作用清理带来的延迟,如果你某些情况下你仍然希望依靠同步执行,可以用
useLayoutEffect
。)
-
react18更新
- Concurrent (Concurrent最主要的特点就是渲染是可中断的。没错,以前是不可中断的,也就是说,以前React中的update是同步渲染,在这种情况下,一旦update开启,在任务完成前,都不可中断。)
- 可中断
- 可被遗弃
- 状态复用
- 创建一个初次渲染或者更新,以前我们用的是ReactDOM.render,现在改用react-dom/client中的createRoot
- 自动批量处理 Automatic Batching
- Concurrent (Concurrent最主要的特点就是渲染是可中断的。没错,以前是不可中断的,也就是说,以前React中的update是同步渲染,在这种情况下,一旦update开启,在任务完成前,都不可中断。)
// 以前: 这里的两次setState并没有批量处理,React会render两次
setTimeout(() => {
setCount(c => c + 1);
setFlag(f => !f);
}, 1000);
// React18: 自动批量处理,这里只会render一次
setTimeout(() => {
setCount(c => c + 1);
setFlag(f => !f);
}, 1000);
-
Suspense
-
Suspense有点像catch,只不过Suspense捕获的不是异常,而是组件的suspending状态,即挂载中。
-
transition 、startTransition、useTransition 组件切换动画
-
useDefereredValue 延迟更新不重要的部分
-