TypeScript

Symbol

Type ‘symbol’ cannot be used as an index type.
issure:https://github.com/Microsoft/TypeScript/issues/24587

Ts 旧版功能缺失,symbol 不可作为 index signature,目前已添加:
feature:https://github.com/microsoft/TypeScript/pull/44512
playground

  1. const symbolKey: symbol = Symbol('key');
  2. interface A {
  3. a?: string;
  4. b?: number;
  5. [key: `x-${string}` | symbol]: string; // 可检测熟悉是否是 x- 开头的 string
  6. }
  7. const a: A = {
  8. 'x-a': '123',
  9. 'y-a': '123', // 错误
  10. [symbolKey]: '123'
  11. }

同时 Ts 在类型层面开始支持部分模式匹配的功能。
image.png

React

memo

当需要性能优化,或阻断无效rerender的场景,进行 memo 添加。
但 memo 添加前,先查看当前 组件使用的 props,是否存在 无效渲染 + 可阻断

  1. 无效渲染:当前 props 不应该变化,或该变化与当前组件rerender无关
    1. 不应该变化:原因是当前 props 是一个始终变化的引用类型,但不是一个 memo 值(依赖无效),如果需要,将其在上层 useMemo 化(常见cb={() => {}})。
    2. 无关:这是个被错误传递到当前组件的 props,如果当前组件 render 较为复杂,rerender 有一定消耗,考虑将该 props 通过 context 进行透传,或去除完全不需要的 props
  2. 可阻断
    1. 引用类型:props是一个引用类型,且该引用类型引用本身会在需要的时候发生变化,也就是当前组件只需要处理引用变化进行 rerender,添加 memo 进行阻断。该阻断可能会在将来导致 bug,由于业务变更,原先只需要对引用本身的检查,会转变为对属性的检查,此时的 memo 会造成错误阻断,需外部在属性变化时,对引用同时变化,也就是维持 immutable,也称为维持依赖的有效性。所以如果是一个公共组件,需要假设外部不会维持 immutable:
      1. 不添加 memo,添加一层 props 检测层组件,检查引用类型的属性,将props依赖有效化(useMemo 或 useCallback),真实逻辑部分就可按正常进行 memo 阻断。这样的情况实际会造成大量脏检查消耗,按实际情况选用,大概率不需要处理。
      2. 将该属性从引用中分离为基本类型的 props 传递。
    2. 基本类型:如props全是基本类型,直接添加 memo 即可完成阻断,但若props始终会变化,或变化几率很大,该阻断是无意义的,实际根本不需要添加 memo。

所以,公共组件若存在大量引用类型 props,直接不添加 memo 先看看,是比较明智的选择。

memo 与 shallow observable

若通过 props 来获取 shallow 中某属性,可能会发生 memo 错误阻断的情况,因为 shallow 的属性值发生变更,shallow 自身的引用和属性 key 不会产生变化,所以无法通过 observer 提供响应。若存在 props 未变,但从 shallow 获取的属性值,变化了。此时的 memo 对 props 的阻断会造成问题。
问题出现场景:

  1. 组件使用 shallow observable;
  2. 组件通过 props,获取 shallow observable 中的属性;
  3. shallow observable 属性 value 产生变化,但属性 key 未变({a: 1, b: 2},变为 {a: 2, b: 1});

问题本质原因:
observable data 为 mutable,属性变更,引用不变;
shallow 中值的变化,不被 observer 响应;
react state 要求 immutable,mutable 的数据作为状态会导致重绘无法感知。