响应式系统与React |青训营笔记

54 阅读4分钟

React的设计思路

编程的痛点:

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

转换式系统≠响应式系统

React学习

1.React的设计思路

响应式系统

监听事件,消息驱动

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

组件化

组件设计

  • 组件要声明状态和UI的映射
  • 组件有props/state两种状态
  • “组件”可由其他组件组成

总结

  • 组件是组件的组合/原子组件
  • 组件内拥有状态,外部不可见
  • 父组件可将状态传递给子组件

我认为组件化的宗旨在于我们可以将整个系统拆分成多个独立的,可以重用的组件,这些组件都被定义好了明确的功能和接口,我们可以通过组件化来达到功能的复用和可维护性的提升,我们可以只用专注组组件的优化和测试,从而降低了在开发时考虑整个系统的复杂度.

状态归属问题

抽象每一个局部的状态来进行全局的响应

  • React为单项数据流:只能由父组件将状态传递给子组件
  • Dom更新

状态归属

image.png

上图右上角的当前价格数据应当归属到那个组件去管理?

答:属于根节点Root,因为这个属性会被多个子组件共享。

这也导致了一个问题,当多个子组件需要共享数据的时候,就得将共享数据提升到父组件中,这其实是不好的

既然现在知道当前价格是由Root结点管理的,那子组件需要修改当前价格时该怎么办呢?

由于在js中,函数是一等公民,所以可以将函数也作为属性传递给子组件,那么就可以在Root组件中定义一个修改当前价格的函数,然后将这个函数传给子组件,当子组件需要修改当前价格时,就调用该函数即可

状态具有局部性

状态归属于两个节点向上寻找到最近的祖宗节点

思考

  1. React是单向数据流,还是双向数据流?

    单向数据流(永远都是父组件给子组件传东西)

  2. 如何解决状态不合理上升的问题?

  3. 组件的状态改变后,如何更新DOM?

2. React(hooks)的写法


import React , { use State } from 'react'

function Example(){
    const [count,setCount] = useState(0);
    //定义一个新的状态,将会响应 count
    return(
        <div>
            <p> You Clicked {count} times </p>
            <button onClick={() => setCount(count + 1)}>Click me !</button>
        </div>
    );
}

useState

传入一个初始值,返回一个状态,set该状态的函数,用户可以通过该函数来实现状态的修改

useEffect

传入一个函数,和一个数组,数组是状态的数组称作依赖项,该函数再mount是和依赖项被set时会执行

有“副作用”的函数要传入useEffect来执行。副作用代表除了单纯的计算之外,还要做其他的一些事情。比如网络请求,更新DOM,localStorage存储数据等

3.React的实现

Virtual DOM(及时响应)

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

DOM本身是浏览器的组成部分,JS是通过DOMAPI来修改DOM的,但是Virtual DOM是JS内部维护的

7575ea9f72d4e7a8bd235f2cc1b3ea9.jpg

那么设计Diff算法就是最关键的用于实现rerender的步骤

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

4.React状态管理库

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

主要有redux,xstate,mobx,recoil等状态管理库

ab6bf2dcf51e2bbe3529283f5e71178.jpg

状态机

当前状态,收到外部事件,迁移到下一个状态

655d0f8679c707c7aa4eb4921aa747a.jpg

应用级框架科普

  • NEXT.js
  • MODERN.js
  • Blitz