981377660LMT / ts

ts学习
6 stars 1 forks source link

ExoticComponent #562

Open 981377660LMT opened 3 months ago

981377660LMT commented 3 months ago
// TODO: similar to how Fragment is actually a symbol, the values returned from createContext,
// forwardRef and memo are actually objects that are treated specially by the renderer; see:
// https://github.com/facebook/react/blob/v16.6.0/packages/react/src/ReactContext.js#L35-L48
// https://github.com/facebook/react/blob/v16.6.0/packages/react/src/forwardRef.js#L42-L45
// https://github.com/facebook/react/blob/v16.6.0/packages/react/src/memo.js#L27-L31
// However, we have no way of telling the JSX parser that it's a JSX element type or its props other than
// by pretending to be a normal component.
//
// We don't just use ComponentType or FunctionComponent types because you are not supposed to attach statics to this
// object, but rather to the original function.
interface ExoticComponent<P = {}> {
  /**
   * **NOTE**: Exotic components are not callable.
   */
  (props: P): ReactElement | null
  readonly $$typeof: symbol
}
981377660LMT commented 3 months ago

这段注释和代码是关于React中的“异类组件”(Exotic Components)的定义。在React的世界里,大部分组件都是通过普通的JavaScript函数或类来定义的,这些组件可以直接被渲染器调用来生成React元素。然而,有一些特殊的组件,它们并不是直接通过函数或类来定义的,而是通过React提供的特殊API(如createContextforwardRefmemo)创建的。这些特殊的组件在内部实现和行为上与普通组件有所不同,因此被称为“异类组件”。

异类组件的特点包括:

ExoticComponent<P = {}>接口的定义说明了异类组件的这些特性。这个接口接受一个泛型参数P,代表组件的props类型,默认为空对象{}。接口中定义了一个调用签名,表明这个类型的对象在被调用时接受一个类型为P的参数,并返回一个ReactElementnull。需要注意的是,这个调用签名并不意味着异类组件可以像普通函数那样被调用,它更多是为了类型系统的需要。

此外,注释中提到,由于这些异类组件在JSX解析器中的表现与普通组件不同,我们不能简单地将它们视为ComponentTypeFunctionComponent。这是因为与普通组件不同,你不应该将静态属性附加到这些异类组件对象上,而应该附加到原始函数上。

总的来说,ExoticComponent接口是React类型定义中用来描述那些通过特殊API创建、在行为上与普通组件有所不同的组件的一种方式。