学习一款框架,首先得了解它的设计思路,这有利于帮助我们更好的去理解和学习该框架!所以我将从设计思路层面去剖析 React 的特点。
UI 编程的痛点
相信大家学习前端之初,大多都是先学的三件套,没有学框架之前不知道你是否用原生写过项目?如果要你用原生 JS 去实现下面的图的功能,你要怎么实现?不仅选择型号会引起价格和的更新,选择颜色也会引起价格的更新。
其实用 JS 实现起来也是很简单的,只需要给选择型号和选择颜色绑定的按钮绑定点击事件,这些点击事件和【当前价格(currentValue)】绑定在一起,但是每当你点击了之后,都得手动的去更新有关价格的 dom 元素去实时更新 …… 看起来简单,其实很麻烦,操作 DOM 元素多了会显得很混乱,这就是这种过程式编程的漏洞。
由上述例子可以知道用原生 JS 去实现 UI 有以下痛点:
-
状态更新,UI 不会自动更新,需要手动的调用 DOM 进行更新。
-
欠缺基本的代码层面的封装和隔离,代码层面没有组件化。
-
UI 之间的数据依赖关系,需要手动维护,如果依赖链路长,则会遇到 “Callback Hell'”。
响应式与转换式
由上面用原生实现 UI 的痛点可以看出过程式编程是很痛苦的,这种过程式也就是转换式系统的一种设计模式,转换式系统就是着眼于将输入数据从一种形式或结构转换为另一种形式或结构,以满足特定的目的或需求。
但是针对以上 UI 痛点,很明显我们需要的是可以根据状态变化可以去做自动调整和适应的系统,也就是响应式系统。响应式系统能够根据环境变化和用户需求自动调整和适应的系统,这些系统能够对输入和事件做出快速响应,以提供更好的用户体验。
响应式编程可以做到:
-
状态更新,UI自动更新。
-
前端代码组件化,可复用,可封装。
-
状态之间的互相依赖关系,只需声明即可,不需要手动维护。
而 React 也正是采用这种响应式编程的思想。
组件化
如果一个 UI 界面是散漫的,写到哪里算哪里,那么我们管理 UI 界面的数据分工起来也是很混乱的,所以我们要将界面分块管理也就是组件化管理,这些节点可以构成我们组件的虚拟树结构。(如下图)
组件化的大致思想是这样的:
-
组件是组件的组合/原子组件
-
组件内拥有状态,外部不可见
-
父组件可将状态传入组件内部
状态归属问题
组件化了之后我们又面临一个新问题-组件的状态归属问题。
比如上面提到的【当前价格】(currentValue)的变化,那么这个【当前价格】状态属于哪个组件?
应该是属于 Root 节点,因为要统一状态变更,那么当前价格会被颜色和型号的改变而更新,说明它需要在两个子组件都需要获取到【当前价格】这个状态,所以这个状态需要上移到 Root 节点,但是 不是所有的状态都需要上移,大多数状态都具有局部性。比如颜色卡片,只需要把颜色进行整合在组件内部进行遍历获取颜色渲染即可。
总的来说,关于状态归属问题可以总结为 状态归属于两个节点向上寻找到最近的祖宗节点,大多数状态都具有局部性。
那么说完了【当前价格】的归属问题,【当前价格】怎么改变?
在 JS 中, 函数是一等公民,函数可以传来传去,正是利用这种特点,我们可以在 Root 节点中定义一个改变价格的函数 onChangeValue(),将其向下传递,传给型号还有颜色组件,每当型号或者颜色被 onclick 的时候就调用从 Root 传下来的函数去实现 【当前价格】的实时变动。
总的来说,关于状态改变问题可以总结为祖宗节点可以向子节点或者孙节点传递函数去实现状态改变。
组件化设计总结
根据上面组件化和状态归属以及状态改变的讨论我们可以对组件设计有以下三点总结
-
组件声明了状态和 UI 的映射(数据函数关系)。
-
组件有 Props / State 两种状态。(Props:外部映射进来的函数或者状态 / State:内部的私有状态)
-
“组件”可由其他组件拼装而成。
那么有了以上总结,可以想象一下组件代码会是怎么样的?
(单纯想象一下,并不是react就是这样)
组件化组件应该是这样的:
1.组件内部拥有私有犬态State。
2.组件接受外部的Props状态提供复用性。
3.根据当前的State/Props,返回一个Ul。
比如:
总结React的特性
由上述,由 UI 编程痛点出发,从设计层面逐步分析,可以知道 React 是一个基于响应式编程思想、组件化思想的 JavaScript 库,总结有以下特性:
-
组件化:React 采用组件化的设计思路,将用户界面划分为独立、可复用的组件。每个组件都有自己的状态(State)和属性(Props),通过组合和嵌套不同的组件可以构建复杂的用户界面。组件化使得代码具有高度的模块化和可复用性,而且提供了更好的组织代码的方式。
-
声明式编程:React 利用 JSX 语法(一种类似 HTML 的标记语言),采用声明式编程的方式来描述用户界面。开发者只需要关注描述UI的结构和外观,而不需要关心具体的 DOM 操作和状态变更的细节。React 负责根据组件的状态和属性来自动更新和渲染界面,使得代码更加清晰、易于理解和维护。
-
虚拟DOM :React 使用虚拟 DOM(Virtual DOM)来表示用户界面的状态和结构。虚拟DOM是一个轻量级的JavaScript对象树,它映射了实际的 DOM 结构,并在内存中进行操作和计算。React 通过比较虚拟 DOM 的差异,并最小化对实际DOM的操作,实现高效的界面更新和渲染。
-
单向数据流:React 采用单向数据流的数据管理模式。父组件通过属性(Props)向子组件传递数据,子组件不可直接修改这些数据,而是通过回调函数通知父组件进行状态的更新。这种单向数据流模式减少了数据的复杂性和混乱,使得数据的变化更易于追踪和调试。
后记
希望本文能增加大家对 React 特性的认识。本人也是刚开始接触 React,水平有限,如果发现问题或者有需要补充的点欢迎大家通过评论告诉我!!!