React 了解 | 青训营

67 阅读4分钟

React 历史与应用

发展历史

  • 2010年 Facebook 在其 php 生态中,引入了 xhp 框架,首次引入了组合式组件的思想,启发了后来的 React 的设计
  • 2011年 Jordan Walke 创造了 FaxJS, 也就是后来的 React 原型
  • 2012年 在 Facebook 收购 Instagram 后,该 FaxJS 项目在内部得到使用, Jordan Walke 基于 FaxJS 的经验,创造了 React
  • 2013年 React 正式开源,React is a JavaScript library for building user interfaces
  • 至今 React 生态不断完善,各种工具和框架涌现

应用场景

1. 前端应用发开 2. 移动原生应用开发 (React Native) 3. 桌面应用开发 (Electron)

React 设计思路

响应式编程

解决 UI 编程上的痛点

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

状态更新,UI 自动更新

前端代码组件化,可复用,可封装

状态之间的互相依赖关系,只需声明即可

组件化

组件是组件的组合/原子组件:一个组件内可以包含多个组件

组件声明了状态和 UI 的映射:即输入几个状态则返回多少的 UI

组件内拥有状态,外部不可见:组件本身可以设置自身的样式,与外部无关

组件有 Props/State 两种状态:State 代表组件内部的私有状态,Props 代表外部传入的状态

父组件可以将状态传入组件内部:父组件可以控制子组件显示的内容等等

状态归属

React 是单向数据流:子组件可以通过父组件传递函数来调用改变父组件

状态不合理上升:当两个组件中有元素互相影响的时候,就需要找到它们最近的共同父组件来管理状态,这导致了状态的不合理上升

更新组件状态后更新 DOM

生命周期

image.png

React (hooks) 写法

useState()

用于状态更新

useState 返回一个只包含两个项的数组:

  1. 该状态变量当前的 state,最初设置为你提供的初始化 state。
  2. set 函数,调用它可以在响应交互时将 state 更改为任何其他值。
import { useState } from "react"

export default function Home() {
  const [count, setCount] = useState(0);
  return (
    <div>
      <p>You click {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  )
}
  • 注:调用 set 函数不改变已经执行的代码中当前的 state,只会影响下一次渲染中 useState 返回的内容。

    •   如果想在一次运行中多次改变一个值,应该使用更新函数
function addCount() {
  setCount(count + 1); // 1
  console.log(count) // 0
}

function addCount() {
  setCount(count + 1); // 1
  setCount(count + 1); // 1
}

function addCount() {
  setCount(count => count + 1); // 1
  setCount(count => count + 1); // 2
}

useEffect()

它允许将组件与外部系统同步

外部系统:有些组件需要与网络、某些浏览器 API 或第三方库保持连接,它们显示在页面上时不受 React 控制

useEffect 传入两个参数,第二个可选

  • 处理 Effect 的函数:在将组件首次添加到 DOM 之前,React 将运行函数。在每次依赖项变更重新渲染后,React 将执行该函数
  • dependencies?:函数中引用的所有响应式值的列表。响应式值包括 props、state 以及所有直接在组件内部声明的变量和函数,写法形如 [count1, count2]
useEffect(() => {
  document.title = `You clicked ${count} times`;
})

useEffect(() => {
  document.title = `You clicked ${count} times`;
},[count])

React 的实现

  • JSX 不符合 JS 的标准语法 --- 通过 transpile(转译) 实现 JSX 转 JS

  • 返回的 JSX 发生改变时如何更新 DOM --- 通过 Virtul DOM(虚拟 DOM) 赋予 React 声明式 API,React 确保 DOM 匹配该状态

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

    • Diff 的方式

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