Skip to content
On this page

[文献链接](https://ijpqg5zm8j.feishu.cn/docs/doccnf8zVMcqwwjw6TWz5SnoUmf#hX0qpF

Valid JSX Element

一个 JSX Element 合法的返回类型有:

  • ReactElement (<Component />)
  • 数字 (1)
  • 数组 ([1, <Component />, 'str', null, [11, <Component />, false]])
  • 字符串 ("string")
  • null (null)
  • false (false)

但由于 TS 定义问题,如果我们一个 Component 返回的是数字、数组、字符串、false,不能以 <Component />方式调用,只能 {Component()} 调用。

Fragment 的作用

如果觉得 {Component()} 这种方式调用很不爽,不整齐,可以考虑用 Fragment 包裹一下。

<Fragment>{1}<Component />{'str'}{null}{[11, <Component />, false]}</Fragment>

这样就能绕过 TS 类型检查的问题。

Fragment 实质上是个特殊渲染片段,相当于以数组的方式包裹一组组件进行渲染。

key 和 ref

React 组件中 props 有两个保留字段,key 和 ref。

key

key 是用来追踪 React Component 和实际渲染的 DOM 节点用的。默认使用组件所在位置进行标记。

在渲染数组数据时,提供 key 可以提升 React 复用 DOM 节点的能力。

index 作为 key 比 id 快一倍

原因是当组件树某位置的 key 跟之前渲染的同位置节点有变更时,react 会认为源组件不可复用,会执行完整的 unmount 步骤,删除包括真实 DOM 节点在内的所有数据,完全重新初始化该节点。这个性能差距会随着节点复杂度成几何级别的增大。所以,不要听信一些最佳实践所谓的要将 id 作为 key 渲染。弄清楚 react 运行的原理,才能做出恰当的选择。

总结一下:

  1. 当渲染的组件是完全受控的组件时,就应该用 index 作为 key,以最大限度复用已有节点数据。
  2. 当渲染的组件有内部 state 时,可以通过改变 key,来重置组件内部 state。

ref

ref 一般用来获取 DOM 节点。

react 本质上将 ref 作为 Mutable 对象来看待,通过 ref 可以反向将子组件的内部方法和状态通过 Mutable 的 ref 传递给父组件。

如果是自定义组件,在这里不推荐用 ref,因为写起来麻烦,且容易内存泄漏。

ref 的正确使用方式及副作用回收

ref 作为 React 中唯一的 Mutable 传递方式,形成了一套独特的使用范例。如果传给 ref 的是一个函数,这个函数的调用有以下规则:

  1. 如果 ref 函数跟上一次的 ref 函数不一致(引用比较),那么会在上一次渲染的 useLayoutEffect / useEffect 的回收函数调用后调用,且调用参数为 null,在本次渲染的 useLayoutEffect / useEffect 的回调函数之前,用 reference 实例调用一次 ref 函数。
  2. 如果 ref 函数跟上一次的 ref 函数一致,则重绘时不会调用 ref 函数。

受控与非受控的决策

受控组件:

没有内部状态或内部状态完全由 props 决定的组件

非受控组件:

存在不受 props 控制的内部状态的组件

受控组件的优缺点

优点

受控组件由于完全受父组件的传参控制,意味着使用多个受控组件时,可以在父组件自然而然的访问、修改所有组件状态。当有多个受控组件状态通信、联动的时候,父组件可以方便的根据需求更新子组件状态。

缺点

组件状态不闭环,性能差。受控组件所有状态存放在父组件,导致受控组件需要更新 UI 时,需要通过触发父组件的状态更新来更新自身,父组件的更新会触发所有子组件更新。

性能问题常见在 CRUD 列表和复杂表单业务中出现。受控组件即使完全独立于其他兄弟组件,更新时也会触发兄弟组件的重绘。

使用较复杂,因为 props 传参多。不利于父组件分离关注点。

非受控组件优缺点

优点

非受控组件的优缺点正好和受控组件相反。优点是性能好,更新不依赖父组件,从而避免触发兄弟组件更新。由于逻辑高内聚,对父组件传参依赖少,使用也更简单。

缺点

非受控组件的重置和关联更新比较困难、复杂,需要先卸载掉组件再重新初始化,一般使用 key 来解决

MIT Licensed | Copyright © 2021 - 2022