React 基础与实践| 青训营笔记

86 阅读5分钟

1. React 简介与特性

React:用于构建用户界面的 JavaScript 库

1.1 React 特点

  1. 声明式设计 −React 采用声明范式,可以轻松描述应用。
  2. 高效 −React 通过对 DOM 的模拟,最大限度地减少与 DOM 的交互。
  3. 灵活 −React 可以与已知的库或框架很好地配合。
  4. JSX − JSX 是 JavaScript 语法的扩展。React 开发不一定使用 JSX ,但我们建议使用它。
  5. 组件 − 通过 React 构建组件,使得代码更加容易得到复用,能够很好的应用在大项目的开发中。
  6. 单向响应的数据流 − React 实现了单向响应的数据流,从而减少了重复代码,这也是它为什么比传统数据绑定更简单。
  7. 跨平台编写

1.2 React 哲学

React 是用 JavaScript 构建快速响应大型 Web 应用程序的首选方式之一。它在 Facebook 和 Instagram 上表现优秀。

等待资源加载时间和大部分情况下浏览器单线程执行是影响 web 性能的两大主要原因。

等待资源加载

  • 一次请求太多资源
  • 网络请求慢
  • 资源加载失败
React.Lazy
React.Suspense
ErrorBoundary

浏览器线程执行

  • JS 执行
  • 浏览器计算样式布局
  • UI 绘制
异步更新
时间切片
React Fiber
1.2.1 更新流程

1.drawio.png

Scheduler(调度器)

  • 维护时间切片
  • 与浏览器任务调度
  • 优先级调度

Reconciler(协调器)

  • 将 JSX 转化为 Fiber
  • Fiber 树对比(双缓存)
  • 确定本次更新的 Fiber

Renderer(渲染器)

  • 渲染器用于管理一棵 React 树
  • 使其根据底层平台进行不同的调用

2.drawio.png

1.3 总结

优点

  • 快速响应:Fiber
  • 组件化:复用性强
  • 声明式编程
  • 跨平台:只需修改渲染器

缺点

  • 大型应用需要配套学习状态管理、路由工具
  • 不适合小型应用,需要用 babel 处理

2. React 基础温故知新

2.1 用 React 开发 web 应用

架构

打包配置:JSX->babel->JS

加载优化和错误降级

路由

React Router 向应用中快速地添加视图和数据流,保持页面与 URL 间的同步

UI

可复用 UI->组件->页面

可复用逻辑抽离成 hook

状态

多页面多组件共享信息 redux & context

2.2 组件

数据

通过定义 state 操作视图 Mount 时获取数据更新 state

Ref 保存与视图无直接关系的值 unMount 前清空 Ref

通信

props 父子组件通信

context & redux 组件信息共享

UI

数据决定视图

通过 Ref 获取到 DOM

性能

函数使用 useCallback 值或计算使用 useMemo 组件包裹 memo

2.2.1 Class 组件
  • 继承 + 构造函数
  • this
  • 生命周期
  • render 方法
2.2.2 函数式组件
  • 没有生命周期
  • 借助 Hook
  • return JSX
函数式相较于 Class 的优点
  • 代码量骤减,组件干净清爽
  • 没有复杂的生命周期
  • 支持自定义 hook,逻辑复用方便
组件和 Hook 的关系
  • 我们将 UI 拆成多个独立单元,这些单元组合可以构成多种视图展示,这些独立单元就是组件。组件相当于原子
  • hook 贴近组件内部运行的各种概念逻辑,effect、state、context等。hooks 更贴切于电子

2.3 Hook

2.3.1 规则 & 原理

只能在最顶层使用 Hook

React 靠 Hook 调用顺序知道哪个 state 对应哪个 useState。

只能在 React 函数中调用 Hook

  • 在 React 函数组件中或自定义 Hook 中调用
  • 自定义 Hook 必须以 use 开头
  • Hook 中的 state 是完全隔离的
2.3.2 过期闭包问题

在 JS 中,函数运行的上下文是由定义的位置决定的,当函数的闭包包住了旧的变量值时,就出现了过期闭包问题。

2.4 常见 API 及作用

React.COmponent类组件基类 extends
React.PureComponent为实现 shouldComponentUpdate(),内置了 props 和 state 浅层对比
React.memo高阶组件,仅比较 props 变更
React.createElement创建并返回 React 元素,不使用 JSX 场景
React.cloneElement克隆并返回新 React 元素,并且可以为新元素添加额外 props
React.Children.[Fn]map 遍历并返回;forEach 仅遍历;count 子组件数量;only 是否只有一个子节点
React.createRef创建一个 ref,并附加到具体元素上,class 组件中获取 dom 结构常用
React.forwardRef转发 ref 或者与 useImperativeHandler 联合使用暴露方法
React.lazy实现组件动态加载
React.Suspense组件加载过程优雅降级

2.5 常见 Hook 及作用

useState返回一个 state 及更新 state 的函数
useEffect可以让你在函数组件中执行某些操作,挂载时、依赖变化时甚至说卸载前
useContext接收最近的上层 context 对象,并返回其值,一般与 createContext 一起使用
useRef返回一个可变的 ref 对象,在组件生命周期内持续存在
useMemo参数为计算函数和依赖项,只有在依赖项变化时才调用计算函数,返回函数的计算值
useCallbackuseCallback(fn,deps),相当于 useMemo(()=>fn,deps),一般返回的是一个新函数
useRenderuseState 的更丰富替代方案,返回 [state,dispatch],这里 state 可以是复杂对象,dispatch 可以更新这个复杂对象
useImperativeHandler可以给父组件暴露方法,一般与 forwardRef 一起使用
useLayoutEffectuseEffect 的执行时机是浏览器完成渲染之后,而 useLayoutEffect 的执行时机是浏览器把内容真正渲染到界面之前,是和 componentDidMount 等价的