react(杂记)

react整体是函数式的思想,把组件设计成纯组件,状态和逻辑通过参数传入,所以在react中,是单向数据流,推崇结合immutable来实现数据不可变。react在setState之后会重新走渲染的流程,如果shouldComponentUpdate返回的是true,就继续渲染,如果返回了false,就不会重新渲染,PureComponent就是重写了shouldComponentUpdate,然后在里面作了props和state的浅层对比。

React 并不是完整的 MVC/MVVM 框架,它专注于提供清晰、简洁的 View(视图)层解决方案。而又与模板引擎不同,React 不仅专注于解决 View 层的问题,又是一个包括 View 和 Controller 的库。对于复杂的应用,可以根据应用场景自行选择业务层框架,并根据需要搭配 Flux、Redux、GraphQL/Relay 来使用。

两种不同的元素:DOM 元素和组件元素。在 JSX 里自然会有对应,对应规则是 HTML 标签首字母是否为小写字母,其中小写首字母对应 DOM 元素,而组件元素自然对应大写首字母。

state 与 props 是 React 组件中最重要的概念。如果顶层组件初始化 props,那么 React 会向下遍历整棵组件树,重新尝试渲染所有相关的子组件。而 state 只关心每个组件自己内部的状态,这些状态只能在组件内改变。把组件看成一个函数,那么它接受了 props 作为参数,内部由 state 作为函数的内部参数,返回一个 Virtual DOM 的实现。

浏览器原生 DOM 事件的传播可以分为 3 个阶段:事件捕获阶段、目标对象本身的事件处理程序调用以及事件冒泡。事件捕获会优先调用结构树最外层的元素上绑定的事件监听器,然后依次向内调用,一直调用到目标元素上的事件监听器为止。可以在将 e.addEventListener() 的第三个参数设置为 true 时,为元素 e 注册捕获事件处理程序,并且在事件传播的第一个阶段调用。此外,事件捕获并不是一个通用的技术,在低于 IE9 版本的浏览器中无法使用。而事件冒泡则与事件捕获的表现相反,它会从目标元素向外传播事件,由内而外直到最外层。
阻止原生事件传播需要使用 e.preventDefault()

CSS Modules 的命名规范是从 BEM 扩展而来的。BEM 把样式名分为 3 个级别,具体如下所示。

  • Block:对应模块名,如 Dialog。
  • Element:对应模块中的节点名 Confirm Button。
  • Modifier:对应节点相关的状态,如 disabled 和 highlight。

BEM 最终得到的 class 名为 dialog__confirm-button--highlight。使用双符号 __-- 是为了与区块内单词间的分隔符区分开来。

从动画体验的角度来说,不同的缓动函数会带给用户不同的缓动体验。以我们常见的缓动函数 lineareasespring 为例,缓动体验一般为 linear < ease < spring

为什么这么说呢?lineareasespring 其实刚好代表 3 种缓动函数类型。其中,linear 是一种匀速运动, 给人的感觉是机械、呆板、没有生机,只有工厂里的机器是保持速度一成不变的!人们喜欢有生命的运动。

easespring 都是变速运动,那么为什么 spring 的缓动体验要比 ease 更好呢?物理原则是优秀用户体验(UX)的核心原则之一,界面设计遵从物体在真实世界中的运动规律,会让人们感觉更加自然、舒适。

spring 是最经典、最常用的物理缓动过程。而 cubic-bezier(三次贝塞尔曲线) 因为具有很强的控制能力,人们可以非常简单、直观地配置一条 y - t 曲线作为缓动过程。因此,spring 和 cubic-bezier(如 easeease-inease-outease-in-outlinear)在动画中最为常用。

在 Web 开发中,要将更新的数据实时反应到 UI 上,就不可避免地需要对 DOM 进行操作,而复杂频繁的 DOM 操作通常是产生性能瓶颈的原因之一。为此,React 引入了 Virtual DOM 机制。毫不夸张地说,Virtual DOM 是 React 的核心与精髓所在,而 reconciler 就是实现 Virtual DOM 的主要源码。

Virtual DOM 实际上是在浏览器端用 JavaScript 实现的一套 DOM API,它之于 React 就好似一个虚拟空间,包括一整套 Virtual DOM 模型、生命周期的维护和管理、性能高效的 diff 算法和将 Virtual DOM 展示为原生 DOM 的 Patch 方法等。
基于 React 进行开发时,所有的 DOM 树都是通过 Virtual DOM 构造的。React 在 Virtual DOM 上实现了 DOM diff 算法,当数据更新时,会通过 diff 寻找到需要变更的 DOM 节点,并只对变化的部分进行实际的浏览器的 DOM 更新,而不是重新渲染整个 DOM 树。

diff算法:
首先,对新集合中的节点进行循环遍历 for (name in nextChildren),通过唯一的 key 判断新旧集合中是否存在相同的节点 if (prevChild === nextChild),如果存在相同节点,则进行移动操作,但在移动前需要将当前节点在旧集合中的位置与 lastIndex 进行比较 if (child._mountIndex < lastIndex),否则不执行该操作。这是一种顺序优化手段,lastIndex 一直在更新,表示访问过的节点在旧集合中最右的位置(即最大的位置)。如果新集合中当前访问的节点比 lastIndex 大,说明当前访问节点在旧集合中就比上一个节点位置靠后,则该节点不会影响其他节点的位置,因此不用添加到差异队列中,即不执行移动操作。只有当访问的节点比 lastIndex 小时,才需要进行移动操作。

你可能感兴趣的:(javascript)