乐趣区

关于前端:React-入门笔记

React 的历史与利用

React 是一个 JavaScript 库

React : A JavaScript library for building user interfaces.   ——Jordan Walke

  • 利用场景:

    • 前端利用开发,如 Facebook、Instagram、Netflex 网页版
    • 挪动原生利用开发,如 Instagram、Discord、Oculus
    • 联合 Electron,进行桌面利用开发
    • 3D 开发:react-three-fiber
  • React 的历史

    • 2010 年:Facebook 在其 php 生态中,引入了 xhp 框架,首次引入了组合式组件的思维,启发了起初的 React 的设计
    • 2011 年:Jordan Walke 发明了 FaxJS,也就是起初的 React 原型
    • 2012 年:在 Facebook 收买 Instagram 后,该 FaxJS 我的项目在外部失去应用,Jordan Walke 基于 FaxJS 的教训发明了 React
    • 2013 年:React 正式开源,在 2013 JSConf 上 Jordan Walke 介绍了这款全新的框架
    • 2014 年:生态大暴发,各种围绕 React 的新工具 / 新框架开始涌现

React 的设计思路

  • 原生 JavaScript UI 编程痛点

    • 状态更新,UI 不会自动更新,须要手动调用 DOM 进行更新
    • 欠缺根本的代码层面的封装和隔离,代码层面没有组件化
    • UI 之间的数据依赖关系须要手动保护,如果依赖链路过长会引起回调天堂 Callback Hell
  • 响应式与转换式

    • 转换式零碎:给定输出求解输入,例如编译器、数值计算
    • 响应式零碎:监听事件,音讯驱动,例如监控零碎、UI 界面
  • 响应式零碎

    事件 -> 执行既定回调 -> 状态变更

  • 响应式的前端 UI 编程:

    事件 -> 执行既定回调 -> 状态变更 -> UI 更新

  • React 响应式编程特点

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

    • 组件是组件的组合 / 原子组件
    • 组件外部领有状态,内部不可见
    • 父组件可将状态传入组件外部
  • 组件状态归属问题

    • 共享状态归属于两个组件节点的最近先人节点,即状态晋升
    • React 是单向数据流,永远是父组件给子组件传递状态,子组件只能调用函数更改状态
    • 应用状态治理库如 redux 解决状态不合理晋升的问题
    • 如何批改 DOM : 将 JSX 文件本义为 JS 文件、利用虚构 DOM 树和 diff 算法来更新 DOM
  • 组件设计

    • 组件申明了状态和 UI 的映射
    • 组件有 props 和 state 两种状态
    • 组件可由其余组件拼装而成
  • 组件特点:

    • 组件外部领有公有状态 state
    • 组件承受内部的 props 状态提供复用性
    • 依据以后的 state 和 props 返回一个 UI

React Hooks 的写法

  • 最罕用的两个 Hooks 是 useState 和 useEffect
  • useState:传入一个初始值,返回一个状态,和 set 该状态的函数,用户能够通过调用该函数,来实现状态的批改

    import React, {useState} from 'react';
    
    const Example = () => {const [count, setCount] = useState(0);
    return (
      <div>
        <p>You clicked {count} times</p>
        <button onClick={() => setCount(count + 1)}>
          Click me
        </button>
      </div>
    );
    }
  • useEffect:两个参数,一个是要执行的函数,一个是依赖项数组(能够不传依赖性)。有副作用的函数要传入到 useEffect 来执行。副作用示意除了单纯的计算之外还要做其余的事件,比方网络申请、更新 DOM、localStorage 数据等。

    import React, {useState, useEffect} from 'react';
    const Example = () => {const [count, setCount] = useState(0);
    // 应用一个副作用,传入的 [count] 数组使得此副作用只有当 count 变量扭转时才会被调用
    useEffect(() => {
      // 副作用:Update the document title using the browser API
      document.title = `You clicked ${count} times`;
    }, [count]);
    
    return (
      <div>
        <p>You clicked {count} times</p>
        <button onClick={() => setCount(count + 1)}>
          Click me
        </button>
      </div>
    );
    }
  • Hooks 的应用规定:

    • 只在最顶层应用 Hooks,不要在循环,条件或嵌套函数中调用 Hooks,确保总是在 React 函数的最顶层以及任何 return 之前调用他们。
    • 只在 React 函数中调用 Hooks,不要在一般的 JavaScript 函数中调用 Hooks,能够在 React 的函数组件中调用 Hooks,能够在自定义 Hooks 中调用其余 Hooks

React 的实现

  • React 是不能间接在浏览器中运行的,有这些问题

    • React 的 JSX 语法不合乎 JavaScript 规范语法
    • 返回的 JSX 产生扭转时,如何更新 DOM
    • state/props 更新时要从新触发 render 函数
  • 如何实现

    • 将 JSX 文件转译(transpile)成 JS 文件
    • 利用虚构 DOM 树

      • 实在 DOM(Document Object Model)是浏览器创立页面的文档对象模型
      • 虚构 DOM 树是在 JS 内存中保护的一个对象,具备和 DOM 相似的树状构造,并和 DOM 能够建设一一对应的关系
      • 利用虚构 DOM 就不必操作实在 DOM 提供的 API 来批改 DOM 了:它赋予了 React 申明式的 API,通知 React 心愿让 UI 是什么状态,React 就确保 DOM 匹配该状态,前端工程师便能够从属性操作、事件处理和手动 DOM 更新这些操作中解放出来
    • 利用 Diff 算法

      • 状态扭转时,先更新虚构 DOM 树,而不是间接更新 DOM 树,通过 Diff 算法,求出起码要更新的节点,而后再去更新真正的 DOM 树
      • 完满的最小 Diff 算法,须要 O(n^3)的复杂度;就义实践最小 Diff,换取工夫,失去了 O(n)复杂度的算法

        不同类型元素 同类型元素 同类型的组件元素
        替换 更新 递归

React 状态治理库

  • 核心思想:将状态抽离到 UI 内部进行对立治理
  • 状态治理库的弊病:UI 依赖于内部的一个状态治理库会升高代码的复用性,因而状态治理库总是呈现在业务代码中
  • 常见状态治理库:redux、xstate、mobx、recoil
  • 状态机:以后状态收到内部事件,迁徙到下一个状态
退出移动版