初识React | 青训营笔记

95 阅读3分钟

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

React的历史与应用

历史

  • 2010年,Facebook引入的xhp框架出现了组合式组件的思想
  • 2011年,Jordan Walke创造了FaxJS
    • 支持客服端和服务端渲染
    • 响应式:状态改变时UI自动更新
    • 更快的渲染速度,更小的代码体积
    • 函数式声明组件
  • 2012年,Jordan Walke基于FaxJS创造了React
    • 当时作者给React的定义是一个JS库而不是框架

应用

  • web应用
  • 移动端应用
  • 桌面端应用(结合Electron)

React的设计思路

UI编程痛点和解决方案

  • 状态更新时,需要手动操作DOM进行UI的更新——响应式
  • 欠缺基本的代码层面的封装和隔离——组件化
  • UI之间的数据依赖关系,需要手动维护,如果依赖链路长,会遇到回调地狱——声明式

组件化设计思路

  • 组件声明了状态和UI的映射
  • 拥有Props(父组件传入)和State(自身状态)
  • 组件可以由其他组件拼装而成

组件化引出的问题

  • React是单向数据流还是双向数据流?
    • 单向,只能父传子,如果想实现子传父,只能通过父组件传入一个回调函数,由子组件触发该函数实现
  • 如何解决状态不合理上升的问题?
    • 由于只能父传子,所以当多个组件共享一个状态时要进行状态提升,这个问题可以通过状态管理库解决
  • 组件的状态改变后,如果更新DOM?
    • 构建虚拟dom,通过diff算法计算出需要更新的dom节点,然后再去更新对应的真实的dom

生命周期

image.png

Hooks写法入门

两个基本hook:useState和useEffect

import React, { useState, useEffect } from 'react';
function Example() {
  // useState接收一个初始值,返回一个数组,第一个是状态名,第二个是更新状态的方法
  const [count, setCount] = useState(0);
  // useEffect(如果注入状态,则可类比vue3的watchEffect)中可执行副作用操作(除了单纯的计算外,还要进行其他操作如:网络请求、更新DOM、改变浏览器缓存)
  useEffect(() => {    
    document.title = `You clicked ${count} times`;  
  });
  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

使用规则

  • 只在最顶层使用Hook:不要在循环和嵌套中使用Hook
  • 只在React函数中使用Hook:不要在普通的JS函数中使用Hook

React的实现

问题和解决方案

  • JSX不符合JS标准语法——转译
  • JSX改变时如何更新DOM——虚拟DOM + Diff算法
  • State/Props更新时需要重新触发render函数——同上

React下DOM更新流程

image.png

Diff算法——Heuristic O(n) Algorithm

时间复杂度为O(n)——只遍历了一遍DOM树

优化后的算法规则
情况说明操作
不同类型的元素type由input变为button替换
同类型的DOM元素仅有属性(状态)发生变化更新
同类型的组件元素组件名相同递归

React的状态管理库

核心思想:将状态抽离到UI外部进行统一管理

推荐

应用级框架

基于React进行二次开发的框架,集成路由、构建工具等

推荐

  • Next.js:稳定、开发体验好
  • Modern.js:全栈开发,内置很多开箱即用的工具
  • Blitz:无API思想,直接操作数据库