Aimee

personal blog

欢迎来到我的个人站~


react 相关

react fiber

  • fiber 架构目的
    • 为了使react渲染的过程中可以被中断,将控制权交还给浏览器,可以让位给高优先级的任务,浏览器空闲之后再恢复渲染,对于计算量比较大的js计算或者dom计算,不会显得卡顿,有规律的执行任务
  • generator 有类型中断的功能,为什么不直接使用
    • 要使用generator ,需要将所有代码包装成generator的形式
    • generator 内部是要有状态

如何判断当前是否有高优先级任务?

 - 约定一个合理的执行时间,当超过这个执行时间,如果任务还没结束,中断当前任务,将控制权交还给浏览器
 时间计算 1000ms/60f = 16ms
 requestIdleCallback 使浏览器在有空的时候执行我们的回调,这个回调传入一个参数,表示浏览器有多少时间供我们执行任务

 - 浏览器在一帧内要做什么事情
   - 处理用户输入事件
   - js执行
   - requestAimations 调用
   - 布局 layout
   - 绘制 paint

浏览器很忙的时候怎么办?

  • requestIdleCallback timeout 参数,如果超过这个timeout后,回调还没被执行,那么会在下一帧强制执行回调

  • 兼容性???
    • requestIdleCallback 兼容性很差,通过messageChannel 模拟实现了requestIdleCallback的功能
  • timeout超时一定会执行吗???
    • 不是的,react 里预定了5个优先级的等级

    • Immediate 最高优先级,这个优先级的任务应该被马上执行不能中断
    • userBlocking 这些任务一般是用户交互的结果,需要及时得到反馈
    • normal 不需要用户立即感受到的变化,比如网络请求
    • low 这些任务可以延后,但是最终也需要执行
    • idle 可以被无限延期的

高阶组件?什么是高阶组件?高阶组件用来做什么?

  • hoc
    • 一个函数
    • 入参: 原来的react组件
    • 返回值: 新的react组件
    • 纯函数,不应该有任何的副作用
  • 做什么?
  • 属性代理
    • 操作props
    • 操作组件实例
  • 劫持/继承

什么是react hook ?有啥优势?

  • 可以不写class组件的情况下,使用state和其他react 特性

useState useEffect useMemo

  • class 组件的缺点
    • 组件间的状态逻辑很难复用
      • 组件间如果有state的逻辑是相似的, class 模式下基本是用高阶组件来解决,虽然能够解决问题,但是我们需要在组件外部包一层元素,会导致层级非常冗余

      • 复杂业务的状态组件会非常复杂,不好拆分

      • 监听和定时器的操作,被分散在多个区域(多个生命周期函数中)

      • this 指向问题

hooks 的优点

  • 利于业务逻辑的封装和拆分,可以非常自由的组合各种自定义hooks(自己封装react hooks的公共逻辑)
  • 可以在无需修改组件结构的情况下,复用组件状态逻辑
  • 定时器 监听。。。都被聚合到同一个代码下

### react hook 的注意事项

    1. 只能在函数内部的最外层调用hook,不要在循环、条件判断或者子函数中调用
    1. 只能在react 的函数组件中调用hook,不要在其他的js函数里调用

#### 为什么hook 不能在循环、条件判断中调用?

    1. 手动实现useState

    // 使用 hook
    function Counter() {
      const [count, setCount] = useState(0);
    }

    // 实现 useState
    let stateArray: any[] = [];
    const index = 0;
    function useState<T>(initialState: T):[T, (newState: T) => void] {
      const current = index;
      stateArray[current] = stateArray[current] || initialState;
      function setState(newState: T) {
        stateArray[current] = newState;
        render();
      }

      index++;

      return [stateArray[current], setState];
    }

#### 为什么useEffect 的第二个参数是空数组,就相当于componentDidMount只执行一次?

const allDeps: Array<any[] | undefined> = []; // 二维数组
let cursor = 0;
 function useEffect(callback: () => viod, depArray?: any[]) {
   if(!depArray) {
     callback();
     allDeps[cursor] = depArray;
     cursor++;
     return;
   }
    // 表示的是上一次的依赖项
   const deps = allDeps[cursor];
  // 依赖项是否更新
   const hasChanged = deps ? depArray.some((el, i) => el !== deps[i]) : true;

   if(hasChanged) {
     callback();
     allDeps[cursor] = depArray;
   }
   cursor++;
 }

#### 自定义的hook怎样操作组件的?