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

93 阅读5分钟

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

这是我参与「第四届青训营 」笔记创作活动的的第 15 天

概述

本节课程主要分为四个方面:

  1. React 的历史与应用 - 介绍 React 的发展历史以及应用场景

  2. React 的设计思路 - 介绍 React 的设计思想,为什么 React 要设计成这样

  3. React hooks 的写法 - 介绍基础的 React hooks 写法,以及常用的 hooks

该课程需要这些前置知识:

  1. HTML,JS,CSS 基础。

  2. 基础的数据结构/算法知识,如二叉树,深度遍历等。

  3. 会使用浏览器提供的 DOM API 来修改 DOM,更新 UI。

课前

体验 React

  1. 访问 reactjs.org/docs/gettin… 体验 React 框架

React 历史与应用

应用场景

  1. 前端应用开发,如 Facebook,Instagram,Netflix 网页版
  2. 移动原生应用开发,如 Instagram,Discord,Oculus
  3. 结合 Electron ,进行桌面应用开发

发展历程

  • 2010 年 Facebook 在其 php 生态中,引入了 xhp 框架,首次引入了组合式组件的思想,启发了后来的 React 的设计

  • 2011 年 Jordan Walke 创造了 FaxJS ,也就是后来的 React 原型

    Pasted image 20220807105637.png

  • 2012 年 在 Facebook 收购 Instagram 后,该 FaxJS 项目在内部得到使用,Jordan Walke 基于 FaxJS 的经验,创造了 React

  • 2013 年 React 正式开源,在 2013 JSConf 上 Jordan Walke 介绍了这款全新的框架

    Pasted image 20220807105903.png

  • 2014 年 - 今天 生态大爆发,各种围绕 React 的新工具/新框架开始涌现

    Pasted image 20220807110057.png

React 的设计思路

UI 编程痛点

  1. 状态更新,UI 不会自动更新,需要手动地调用 DOM 进行更新
  2. 欠缺基本的代码层面的封装和隔离,代码层面没有组件化
  3. UI 之间的数据依赖关系,需要手动维护,如果依赖链路长,则会遇到 "Callback Hell"

响应式与转换式

转换式系统:给定输入求解输出

  • 编译器
  • 数值计算

响应式系统:监听事件,消息驱动

  • 监控系统
  • UI 界面

响应式系统的执行步骤:

  1. 事件
  2. 执行既定的回调
  3. 状态变更

响应式编程

前端 UI 执行步骤:

  1. 事件
  2. 执行既定的回调
  3. 状态变更
  4. UI 更新

响应式编程:

  1. 状态更新,UI 自动更新
  2. 前端代码组件化,可复用,可封装
  3. 状态之间的相互依赖关系,只需声明即可

组件化

  1. 组件是 组件的组合/原子组件
  2. 组件内拥有状态,外部不可见
  3. 父组件可将状态传入组件内部

组件设计:

  1. 组件声明了状态和 UI 的映射
  2. 组件有 Props/State 两种状态
  3. 组件可由其他组件拼装而成

组件代码:

  1. 组件内部拥有私有状态 State
  2. 组件接受外部的 Props 状态提供复用性
  3. 依据当前的 State/Props ,返回一个 UI

状态归属问题

父组件将状态传入子组件

状态归属于两个节点向上寻找到最近的祖宗节点

React 是单向数据流

生命周期

Pasted image 20220807122436.png

React(hooks)的写法

import React, { useState } from 'react';

function Example() {
  // Declare a new state variable, which we'll call "count"
  const [count, setCount] = useState(0);
  
  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}
import React, { useState, useEffect } from 'react';

function Example() {
  const [count, setCount] = useState(0);

  // Similar to componentDidMount and componentDidUpadate:
  useEffect(() => {
    // Update the document title using the browser API
    document.title = `You clicked ${count} times`;
  });

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

hooks 写法入门

useState

  • 传入一个初始值,返回一个状态,和 set 该状态的函数,用户可以通过调用该函数来实现状态的修改。

useEffect

  • 传入一个函数,和一个数组,数组是状态的函数,称作依赖项,该函数在 mount 时,和依赖项被 set 的时候会执行。

Hook 使用法则:

  • 不要在循环、条件或嵌套函数中调用 Hook

React 的实现

问题

  1. JSX 不符合 JS 标准语法

    转译 Pasted image 20220807151350.png

  2. 返回的 JSX 发生改变时,如何更新 DOM

    Virtual DOM (虚拟 DOM)

    Virtual DOM 是一种用于和真实 DOM 同步,而在 JS内存中维护的一个对象,它具有和DOM 类似的树状结构,并和DOM 可以建立一一对应的关系。

    它赋子了 React 声明式的 API:您告诉 React 希望让 UI 是什么状态,React 就确保 DOM 匹配该状态。这使您可以从属性操作、事件处理和手动 DOM 更新这些在构建应用程序时必要的操作中解放出来。

    Pasted image 20220807151906.png

    TradeOff :

    • 更新次数少
    • 计算速度快

    完美的最小 Diff 算法,需要 O (n^3) 的复杂度。

    牺牲理论最小 Diff ,换取时间,得到 O (n)

    Heuristic O (n) Algorithm

    How to Diff :

    • 不同类型的元素 - 替换
    • 同类型的 DOM 元素 - 更新
    • 同类型的组件元素 - 递归
  3. State/Props 更新时,要重新触发 render 函数

React 状态管理库

核心思想

将状态抽离到 UI 外部进行统一管理

缺点:降低组件的复用性

推荐

redux、xstate、mobx、recoil

状态机

当前状态,收到外部事件,迁移到下一个状态

应用级框架科普

  1. NEXT.js

    硅谷明星创业公司 Vercel 的 React 开发框架,稳定,开发体验好,支持 Unbundled Dev,SWC 等,其同样有 Serverless 一键部署平台帮助开发者快速完成部署。口号是 "Let's Make Web Faster"

  2. Modern.js

    字节跳动 Web Infra 团队研发的全栈开发框架,内置了很多开箱即用的能力与最佳实践,可以减少很多调研选择工具的事件。

  3. Blitz

    无 API 思想的全栈开发框架,开发过程中无需写 API 调用与 CRUD 逻辑,适合前后端紧密结合的小团队项目。

课后

  1. 学习了解 next.js 框架 nextjs.org/