响应式系统与 React | 青训营笔记

172 阅读13分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 16 天

1 历史与应用

React和React Native的主要区别是,React是一个前端JavaScript库,而React Native是一个移动应用框架。

  • React,也被称为ReactJS或React.js,是一个免费和开源的JavaScript库。它是一个前端JavaScript库,用于开发基于UI组件的交互式用户界面。你可以使用React作为开发单页或移动应用程序的基础。

现代网站大多遵循模型-视图-控制器(MVC)架构。在MVC架构中,React是 "V",代表着 "视图"。

一个React应用程序由多个组件组成,其中每个组件都是使用一小段可重复使用的HTML代码开发的。我们可以将这些组件与其他React组件一起使用,构建复杂的应用程序。

  • React Native,也被称为RN,是一个开源的UI软件框架。它是建立在React库之上的。它是一个基于JavaScript的移动应用框架,允许我们为Android和iOS建立原生渲染的应用程序。

有了这个框架,我们可以通过使用React框架的原生平台功能,为Windows、macOS、Android、iOS、Android TV、tvOS、Web和UWP开发应用程序。此外,React Native支持同时为安卓和iOS开发移动应用,因为我们可以编写可以在两个平台之间共享的代码。

Electron 是一个基于 Chromium 和 Node.js 的跨平台桌面应用程序开发框架,它使用 HTML、CSS 和 JavaScript 来构建桌面应用程序。Electron 可以让开发人员使用 Web 技术来开发桌面应用程序,同时具有原生应用程序的体验和性能。

以下是 Electron 的主要特点:

  1. 跨平台:Electron 可以在 Windows、macOS 和 Linux 等主流操作系统上运行,使得开发人员可以在一个代码库中构建多个平台的桌面应用程序。
  2. 基于 Web 技术:Electron 使用 Web 技术来构建应用程序,包括 HTML、CSS 和 JavaScript,可以使用丰富的前端框架和库,如 React、Vue 和 Angular 等。
  3. 原生体验:Electron 使用 Chromium 来渲染应用程序,可以提供原生应用程序的体验和性能,如菜单、对话框、窗口控制等。
  4. Node.js 集成:Electron 集成了 Node.js,可以使用 Node.js 的模块和 API,如文件系统、网络、进程管理等。
  5. 社区活跃:Electron 的开发和维护由 GitHub 社区进行,有大量的插件和工具可供使用。

Electron 的开发过程包括以下几个步骤:

  1. 安装 Electron:使用 npm 或者 yarn 命令安装 Electron 和相关依赖。
  2. 创建 Electron 应用程序:使用 Electron 命令行工具创建新的 Electron 应用程序,可以选择使用预设的模板或者自定义应用程序。
  3. 编写应用程序代码:使用 HTML、CSS 和 JavaScript 编写应用程序代码,可以使用丰富的前端框架和库。
  4. 调试和测试:使用开发工具和模拟器进行调试和测试,可以在不同的平台和环境中进行测试。
  5. 打包和发布:使用 Electron 命令行工具进行打包和发布,可以将应用程序打包为可执行文件或者安装程序,并发布到应用商店或者网站上。

组合式组件是一种 React 组件设计模式,它通过将多个小型组件组合在一起来构建更复杂的组件。组合式组件可以让开发人员将代码拆分为可重用的部分,从而提高代码的可读性、可维护性和可测试性。

组合式组件的主要思想是将组件看作是一组独立的部分,每个部分都有自己的功能和状态。组件可以通过嵌套和组合来实现更复杂的功能。具体来说,组合式组件可以通过以下两种方式来实现:

  1. Props:可以通过 props 将一个组件作为另一个组件的子组件传递进去,从而实现组件的嵌套和组合。
  2. Render Props:可以通过将一个函数作为 props 传递给另一个组件,从而实现组件的复用和可定制化。

组合式组件的优点包括以下几个方面:

  1. 可重用性:组合式组件可以将代码拆分为可重用的部分,从而提高代码的可重用性和可维护性。
  2. 灵活性:组合式组件可以通过嵌套和组合来实现更复杂的功能,具有较高的灵活性和可扩展性。
  3. 可测试性:组合式组件可以通过单元测试来测试每个小组件的功能和状态,从而提高代码的可测试性和可靠性。

组合式组件在 React 中得到了广泛的应用,例如 React Router、React Redux 和 Ant Design 等开源组件库。开发人员可以使用组合式组件来实现更灵活、可重用和可测试的组件,从而提高代码的质量和可维护性。

  • ClientServer都一起渲染
  • 响应式,根据state改变,我们只需要关注state
  • 性能好
  • 组件级别的复用封装,函数式声明

2 React的设计思路

React 的设计初衷是为了解决 Web 应用程序中的 UI 渲染和交互问题。在传统的 Web 开发中,页面中的 UI 是由 HTML 和 CSS 直接渲染出来的,交互和动态效果是通过 JavaScript 来操作 DOM 和 CSS,这种方式会导致代码量庞大、复杂度高、维护成本大的问题。

React 的设计思想是将 UI 抽象为组件,将组件的渲染和交互逻辑分离出来,通过 Virtual DOM 和组件生命周期等机制来优化 UI 渲染性能和用户体验。React 提供了一种声明式的编程模型,可以更容易地描述 UI 和交互逻辑,同时具有良好的可复用性、可维护性和可测试性。

React 的主要特点包括以下几个方面:

  1. 组件化开发:React 将 UI 抽象为组件,每个组件有自己的状态和行为,可以实现组件的复用和组合。

  2. 虚拟 DOM:React 使用 Virtual DOM 技术来优化 UI 渲染性能,可以避免频繁的 DOM 操作和重绘,提高页面渲染速度和用户体验。

  3. 声明式编程:React 提供了一种声明式的编程模型,可以更容易地描述 UI 和交互逻辑,避免了复杂的 DOM 操作和回调函数。

    1.   声明式编程是一种编程范式,与命令式编程相对。在声明式编程中,开发者只需要描述想要得到的结果,而不需要明确指定具体的实现方式。相反,在命令式编程中,开发者需要明确指定每个步骤的实现方式。
    2.   声明式编程通常基于一些抽象层次,将问题分解为更小的问题,并且使用已经定义好的函数和数据类型来描述解决方案。开发者不需要关心每个细节的实现方式,只需要关心问题本身的表达和解决。
    3.   在声明式编程中,开发者通常使用函数式编程的技术来实现,比如函数组合、高阶函数、惰性求值、纯函数等。这些技术可以帮助开发者更轻松地描述解决方案,并且让代码更加可读、可维护和可测试。
    4.   声明式编程的优点包括:
    5. 更简洁:声明式编程通常使用高阶函数等技术来抽象掉冗余的细节,代码更加简洁。
    6. 更可读:声明式编程让代码更加直观和易懂,开发者可以更快地理解代码的意图。
    7. 更易维护:声明式编程可以帮助开发者更容易地理解和修改代码,减少错误和调试时间。
    8. 更易测试:声明式编程通常使用纯函数等技术来实现,使得代码更容易测试。
    9.   常见的声明式编程范式包括函数式编程、响应式编程、逻辑编程等,应用于许多编程领域,如前端开发、后端开发、数据处理、人工智能等。在前端开发中,React 和 Vue 等框架广泛应用了声明式编程的思想,使得开发者可以更轻松地开发高效、可维护的 UI 组件。

每当点击,都要改变这个价格

多个callback

修改currentValue变量

手动调用DOM接口,修改UI

会挂载很多onclick

过程式编程

响应式系统

  • 监听事件
  • 针对事件进行什么反应

所以JS是异步的

不需要手动维护,只需要声明即可

DOM和UI存在一一对应

DOM不是JS内部的,需要通过API调用

父组件应该可以控制子组件

接口

当多个组件需要共享一个组件的话,需要将组件上移

但是失去了组件复用的初衷了

5 React状态管理库可以解决这个问题

除此之外,大部分组件具有局部性(相邻的放在一起)

在计算机科学中,一等公民(First-Class Citizen)指的是可以作为变量、参数或返回值等被语言原生支持的实体。具体来说,如果一个编程语言支持某个实体作为一等公民,那么这个实体就可以像其他基本类型一样被操作和传递。

一等公民的概念通常应用于函数式编程语言,因为函数式编程语言中的函数本身就是一等公民,可以像其他数据类型一样被操作和传递。

以下是一些常见的一等公民示例:

  1. 函数:函数是最常见的一等公民,可以作为变量、参数或返回值等被语言原生支持。
  2. 对象:在某些编程语言中,对象也可以作为一等公民,可以像其他类型一样被操作和传递。
  3. 数组:在某些编程语言中,数组也可以作为一等公民,可以像其他类型一样被操作和传递。
  4. 类型:在某些编程语言中,类型也可以作为一等公民,可以像其他类型一样被操作和传递。

一等公民的概念在编程中非常重要,因为它可以提高代码的可读性、可维护性和可复用性,使得开发者可以更自由地组织和传递代码,从而实现更高效的开发。

因为函数是一等公民,可以将函数一路传下去

  • 是单向的,不会往回传;永远是父组件给子组件传

    • 但是不代表子组件不能改变父组件,因为可以把函数往下传
  • 状态管理库

  • 后面会讲

  • Props:外部传入的状态,开放接口
  • State:内部私有状态,外部不可见

还能传给子组件

挂载到DOM上(Mounting)

每次有更新又会执行render

当组件mount结束会执行componentDidMount函数

3 React(hooks)的写法

在react里手动调用一个新状态,需要使用useState

数组,第一个是状态本身,后面是setter,不是直接count=count+1,而是setCount(count)

useEffect有副作用;一旦有副作用,就要用useEffect,执行时机是在组件mount的时候执行一次

.tsx 是 TypeScript 的一种文件类型,用于编写 React 组件和应用程序。它是基于 TypeScript 的 JSX 语法扩展,并且可以支持在 JSX 语法中使用 TypeScript 的类型检查和语法提示功能。

React 是一个基于 JavaScript 的库,它允许开发者使用组件化的方式来构建用户界面。JSX 是 React 中常用的一种语法,它允许开发者使用类似 HTML 的语法来描述组件的结构和样式。然而,JSX 并不是标准的 JavaScript 语法,这就导致了在类型检查和语法提示等方面存在一些问题。

TypeScript 是一个基于 JavaScript 的静态类型检查器,它可以在编译时检查代码中的类型错误,并提供更好的语法提示和代码补全。TypeScript 可以与 React 结合使用,并且可以通过 .tsx 文件来支持在 JSX 语法中使用 TypeScript 的类型检查和语法提示功能。

使用 .tsx 文件编写 React 组件和应用程序,可以使得代码更加可读、可维护、可测试和安全。它可以通过类型检查来避免一些潜在的类型错误,并且可以提供更好的语法提示和代码补全,使得开发效率更高。

React Hooks 是 React 16.8 版本引入的一项新功能,它们是一组可以让你在函数组件中“钩入” React state 和生命周期等特性的函数。

在 React 16.8 之前,函数组件没有 state 和生命周期的概念,只能接收 props 并渲染 UI,而 state 和生命周期等特性只能在类组件中使用。这就导致了在开发一些简单组件时,需要创建类组件并实现生命周期方法,增加了代码量和学习成本。React Hooks 的出现解决了这个问题,它允许函数组件拥有自己的 state 和生命周期等特性,让开发者可以使用更少的代码实现同样的功能。

React Hooks 包括多个钩子函数,其中最常用的是 useState 和 useEffect。

useState 允许我们在函数组件中定义 state,并返回一个数组,其中第一个值是当前 state 的值,第二个值是更新 state 的函数。我们可以调用更新 state 的函数来改变 state 的值。

useEffect 则允许我们在函数组件中执行副作用操作,比如订阅和取消订阅事件、请求数据等。useEffect 接收一个函数作为参数,该函数将在组件渲染完成之后被调用,并在组件卸载之前执行清理操作。

除了 useState 和 useEffect,React Hooks 还包括 useContext、useRef、useCallback、useMemo 等钩子函数,它们可以让我们在函数组件中使用更多的 React 特性。使用 React Hooks 可以让我们写出更简洁、可读性更高的代码,并提高代码的可维护性和重用性。

使用tips:不要在循环、条件、嵌套里面调用hooks

4 React的实现

P1:

render函数就是组件函数本身

转译

P2:

客观事实:DOM的挂载很大

我们想到用一个dif函数,找出不同的就行,但是dif函数本身性能也还要好

既然所有的前端框架都是申明式的,为什么浏览器不能直接支持声明式语法?

因为浏览器需要自由度,只能提供底层逻辑

diffing是递归的render

diff算法

启发式的

并没有严谨的证明,只是猜测

不同类型的:整个替换

5 React 状态管理库

问题:状态和外部store强耦合,依赖很强;一般出现在业务代码,库不会这样

什么状态需要放到Store里:是否是全局的,经常被用的

6 应用级别的框架

Next.js

Modern.js