React入门知识

122 阅读7分钟

React是一个用于构建用户界面的Javascript库。它具有声明式、组件化和跨平台的优点。

本文将围绕着以下内容展开:

  1. 一些基本概念
  2. 什么业务场景下需要使用React
  3. 什么是组件,组件的组成部分
  4. 组件渲染过程
  5. 使用useEffect与外部交互

一些基本概念

命令式编程(Imperative):详细的命令程序(How)去处理一件事情以达到最终目的。

声明式编程(Declarative):只告诉程序需要达成的目的(What),具体的过程由程序自己摸索处理。

纯函数(Pure function):输入同样的数据,在任何上下文环境中得到的结果是一致的。可以理解为数学概念中的公式

文档对象模型(DOM):DOM是W3C定义操作标记语言(html/xml)的规范,DOM可以被任何的编程语言实现,浏览器实现了javascript版本的DOM,这是使得浏览器能够通过javascript操作网页内容

虚拟DOM(Virtual DOM):是React模拟的真实DOM的javascript对象。

什么业务场景下需要使用React

浏览器显示html内容的大致过程是:首先把html标签解析为DOM树,然后绘制DOM树内容到屏幕上。通过浏览器提供的Web接口,可以通过javascript动态的更新DOM节点的内容,DOM的更新会触发浏览器重新的绘制最新的内容到屏幕。

html → DOM树 → 绘制 → 更新DOM → 重新绘制。

而React则不同,它是通过浏览器提供的Web接口来更新DOM。React使用跟html类似标记语言jsx来创建元素,项目发布的时候,会把jsx编译为具体的javascript代码(React.createElement)。

React项目显示网页内容的大致过程如下:首先React.createElement创建虚拟DOM,然后比较虚拟DOM和真实DOM之间的差异,把有差异的部门提交给浏览器绘制。

React创建虚拟DOM → 比较虚拟DOM和真实DOM差异 → 同步差异到真实DOM → 浏览器绘制

与直接通过html绘制网页内容不同,React提供了虚拟DOM这个中间层,使得React有能力做到更加精准的按需更新真实DOM,从而提升网页性能(浏览器绘制是一个高消耗操作)。

通过上面的介绍可以看出,React对于业务交互状态复杂的项目更有优势,因为它能做到按需更新,减少浏览器绘制的次数,从而提升网页性能。相反的,对于业务交互状态简单的项目,使用React来构建有点杀鸡用牛刀。

React的组件可以允许你把UI拆分为功能独立的代码片段,可以让开发者专注于更小粒度的代码逻辑。通过组合多个组件来创建复杂的UI。

总结

以下场景可以考虑使用React来构建

  • 交互状态复杂
  • UI复杂

什么是组件,组件的组成部分和运行过程

组件是功能独立的代码片段,是特殊的函数,它的特殊之处在于函数的返回值必须是通过React.createElement来生成。以函数的视角来理解组件会清晰很多。定义组件就是定义函数,使用组件就是函数调用。

定义组件

const Logo = () => {
  return <h1>LOGO</h1>; //jsx被编译后为React.createElement("h1", null, "LOGO");
};
const Header = () => {
  return (
    <>
      <Logo />
    </>
  );
};

以上代码定义了LogoHeader 两个组件,其中Header使用了Logo

如果已函数的视角来理解是这样的:定义了LogoHeader两个函数,在Header中调用了Logo这个函数。

组件的组成部分

组件是一个特殊的函数,函数有的特性,组件也有,它特殊之处在于:

  • 函数的参数必须是immutable,函数参数就是组件的props
  • 函数必须有返回值,并且返回值都使用react.createElement接口创建

只有参数和返回值的组件,称之为Pure组件。

组件除了需要外部传入的props数据外,有些场景也需要内部可改变的私有数据,在React中称为state,state类型的数据具有以下特点:

  • state数据是mutable
  • 只能在组件内部修改,使用set函数(useState/useReducer)更新
  • state更新会触发react的重新渲染的请求
  • state能在同一个组件实例多次渲染共享数据
  • state数据独立于组件之外,由React维护。组件的渲染就是函数的调用,属性的更新会触发组件的重新渲染,多次渲染之后state的值依旧能保持,那么state只能存在于组件之外,否则组件每次重新渲染都会导致state被重置

总结

组件由以下部分组成:

  • props,不可变数据,由使用方传入
  • state,内部可变数据,由组件内部更新
  • 返回值,每个组件的返回值都是用react.createElement创建

组件的渲染过程

所有组件在被浏览器绘制之前,都必须先由React渲染,然后在由React提交给浏览器绘制。理解这个渲染过程有助于了解组件的代码是如何被执行的。

组件从使用到最终被浏览器绘制大约会经历以下3个步骤:

  • 触发渲染请求,React接受到渲染请求后,会将其加入渲染队列
  • 执行渲染,执行相关的组件函数内的代码,执行函数的过程就是React渲染,渲染结束后React会生成一个结果(包含需要更新的DOM信息)进入下一步
  • 提交结果,把最新的UI信息同步给浏览器绘制
  • 执行useEffect设置的函数(可选),本节讨论会忽略这个过程

有以下两个原因会触发渲染请求:

  • 初始化,React项目在第一次启动的时候,会创建初始化渲染的请求
  • 重新渲染,通常state、props、Context的变化都会触发渲染请求

初始化渲染的过程

  • 触发渲染。在项目入口中调用createRoot(rootEl).render(<Component />)
  • 执行渲染。执行相关的组件函数生成虚拟DOM节点
  • 提交结果。使用Web API的appendChild(),把全部的虚拟DOM交给浏览器绘制

重新渲染的过程

  • 触发渲染。一旦初始化渲染完成之后,可以通过更新state触发重新渲染,React会把请求加入的渲染队列。
  • 执行渲染。调用函数,根据组件相关信息生成最新的组件快照,用最新组建快照和上一次的组件快照比较,如果没有任何区别,则什么也不做,否则进入到下一步。
  • 提交结果。React会计算出一个最小更新结果,交给浏览器绘制。

使用useEffect与外部交互

外部指:任何不被react管理的代码部分都叫做外部。

useEffect让组件有了与外部交互的能力,使用useEffect需要传递2个参数:

  • setup函数,这个函数用于与外部系统交互,并返回一个cleanup函数,用于组件被重新渲染前执行清理操作。
  • 依赖列表,初始化渲染完成之后,会执行setup函数(在开发环境中的StrictMode会被调用两次),重新渲染组件会根据依赖列表是否发生变化来决定是否执行setup函数。如果不设置依赖列表,setup函数会在每次渲染完成之后都会执行。如果设置一个空数组[] 则setup只会在初始化渲染的时候被调用

参考资料