前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >使用 TypeScript 的 React 组件点表示法

使用 TypeScript 的 React 组件点表示法

作者头像
小弟调调
发布2022-11-08 13:04:13
1.7K0
发布2022-11-08 13:04:13
举报
文章被收录于专栏:埋名

这篇文章将深入探讨使用组件点表示法时的这些优势,重点介绍一些问题,并提供一些示例。

什么是组件点符号?

顾名思义,它使用“点”来访问对象的属性,通常称为点表示法。但是,由于这是在组件级别(仍然只是对象),为了清楚起见,我更喜欢“组件点表示法”。一个简单的例子是 React Context (https://reactjs.org/docs/context.html)。

代码语言:javascript
复制
const ThemeContext = React.createContext("light");

class App extends React.Component {
  render() {
    return (
      <ThemeContext.Provider value="dark">
        <ThemedButton />
      </ThemeContext.Provider>
    );
  }
}

function ThemedButton(props) {
  return (
    <ThemeContext.Consumer>
      {theme => <Button {...props} theme={theme} />}
    </ThemeContext.Consumer>
  );
}

在此示例中,创建了 ThemeContext 并且是顶级组件。 ProviderConsumer 都是 ThemeContext 的子组件,使用点符号访问。

定义

这些术语将在帖子的其余部分中使用。

•顶级组件:实际导入的组件(例如:ThemeContextFlex)。每组组件只有一个。•子组件:使用点符号访问的任何组件(例如:ThemeContext.ProviderFlex.Item)。每组有一个或多个组件。•组件点符号:使用点符号从顶级组件访问子组件。

为什么使用组件点表示法?

在使用组件点符号来维护和使用一组组件时,我体验到了一些关键的好处。

✏️ 命名空间

由于使用组件点表示法,所有子组件本质上都由顶级组件命名。我们以一个包装了 CSS flexboxFlex 组件为例。顶层组件名为 Flex,带有一个子组件:Flex.Item

代码语言:javascript
复制
import { Flex } from "flex";

function User() {
  return (
    <Flex align="center">
      <Flex.Item shrink={0} grow={0}>
        <Avatar />
      </Flex.Item>
      <Flex.Item shrink={1} grow={1}>
        <UserInfo />
      </Flex.Item>
    </Flex>
  );
}

它不会强制或停止使用 FlexFlex 之外的项目,但由于它是一个子组件,它确实暗示任何可能使用它的开发人员,它应该只用作 Flex 的子组件。

🚢 单一导入

使用这种技术,只有一个入口点可以使用 flex 组件。 Flex.Item 组件定义和逻辑是否与 Flex 在同一个文件中、在同级文件中或在嵌套目录中都没有关系。底层实现和文件结构可以随时更改,因为唯一的公共合约是 Flex 的导出。与单独导入每个组件相比,这减少了“公开”API 过多,其中实现或文件结构的更改将破坏现有用法。

随着功能随着时间的推移而发展,并且由于需求的变化而添加和删除部分,导入可以保持不变,这可以减少导入更改的噪音。

🔍 可发现性

如果一组中有“n”个组件,则开发人员必须记住所有“n”个组件名称才能知道要导入哪个组件或进行文件搜索以找到他们需要的组件。但是,使用组件点表示法,只需要记住顶级组件,并且所有组件选项都将建议在点之后!没有必要记住。这也提高了可能未知的所有可用组件的可发现性。

例子

当组件点表示法运作良好时,有各种实际示例。例如,像 Flex 这样的包装组件,将 Flex.Item 作为子组件。

代码语言:javascript
复制
class Flex extends React.Component<Props> {
  public static Item = FlexItem;

  public render() {
    // ...
  }
}

或者设计系统中可能具有多个构建块的稍微复杂的组件。例如,一个 Table 组件具有许多子组件,例如 Table.Row、Table.Cell 和 Table.Head,这些子组件只能在 Table 中用作子组件。

代码语言:javascript
复制
class Table extends React.Component<Props> {
  public static Body = TableBody;
  public static Cell = TableCell;
  public static Controls = TableControls;
  public static Head = TableHead;
  public static Header = TableHeader;
  public static Row = TableRow;

  public render() {
    // ...
  }
}

最后,它适用于大型或复杂的组件集,例如具有各种过滤器组件、分页、结果等的搜索功能。

代码语言:javascript
复制
<Search category="Users">
  <Search.Filters>
    <Search.Query title="Search" placeholder="Enter a keyword..." />
    <Search.Facet title="Status" />
    <Search.DateRange title="Application Date" />
  </Search.Filters>
  <Search.PaginationCounter />
  <Search.Sort />
  <Search.Results
    component={UsersCard}
    renderEmpty={UsersNoResults}
    renderLoading={UsersLoading}
  />
</Search>

陷阱

在使用组件点表示法时,您可能会偶然发现一些值得注意的“陷阱”。

高阶组件

在顶级组件上使用更高阶的组件(例如从 react-redux 连接)可能会很棘手。特别是在使用 connect 时,它会将所有静态属性提升到包装组件(大多数高阶组件都会这样做),但不会保留正确的类型。在这种情况下,需要强制转换高阶组件,或者如果可能,避免将高阶组件与顶级组件一起使用。

组件显示名称

如上所述,子组件的底层实现并不重要。在 Flex 的情况下,Flex.Item 组件实现本身可以命名为 NeverCallThisComponentDirectly。这很好,但唯一的缺点是在 React Devtools 中,它会显示为 NeverCallThisComponentDirectly,这可能会非常混乱,因为它从未被直接调用过。

解决此问题的一种方法是在组件上设置 displayName 以匹配它的使用方式。在这种情况下,组件名称仍为 NeverCallThisComponentDirectly,但现在显示名称为 Flex.Item

代码语言:javascript
复制
class NeverCallThisComponentDirectly extends React.Component<Props> {
  public static displayName = "Flex.Item";

  public render() {
    // ...
  }
}

底层实现根本没有改变,但现在组件既用作 Flex.Item,又在 React Devtools 中正确地视为 Flex.Item

函数组件

到目前为止,所有示例都使用类组件,但同样的方法也可以用于函数组件。但是,它需要在类型声明中显式声明子组件。

代码语言:javascript
复制
const Flex: React.FC<Props> & { Item: typeof FlexItem } = () => {
  // ...
};

Flex.Item = FlexItem;

此类型声明使用交集将标准 React 函数组件类型与声明 Item 属性的类型结合起来。然后,这允许以与上面的类组件相同的方式分配和稍后使用 Flex.Item

摇树

这种方法的一个缺点是它可以“打破”摇树。在高层次上,tree shaking 的工作原理是删除未导入或未使用的代码。由于顶级 Search 组件导入并公开了所有子组件,因此即使从未使用过它们也会全部包含在内。但是,如果这是一个实际问题,则可能表明组件点符号的过度使用或组件集不相关。

最后的想法

在使用一组组件时,组件点表示法可能是一种有用的技术。它将 API 表面积最小化为单个导出,保持导入简单并提高可用子组件的可发现性。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-08-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 JSdig 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 什么是组件点符号?
  • 定义
  • 为什么使用组件点表示法?
  • 例子
  • 陷阱
    • 高阶组件
      • 组件显示名称
      • 函数组件
      • 摇树
      • 最后的想法
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档