如何用 HOC 包装每个导出的组件?
How to wrap every exported comopnent with HOC?
我需要向我的 React 函数组件的 ALL 添加添加 [data-test-id]
属性的可能性以进行测试。为了实现这一点,我创建了 withTestId()
HOC,它将可选的属性 testId
添加到包装的组件中,当它被定义时,它将 [data-test-id]
添加到最终的 HTML.
所以当我像这样定义组件时:
<ExampleComponent testId="example" />
它returns:
<div data-test-id="example" />
我遇到的唯一问题是将它应用于每个组件,而无需将它单独包装在每个组件中。所以不要写这样的代码:
function ExampleComponent() { ... }
export default withTestId(ExampleComponent)
我想将所有导出内容打包到我的 index.ts
文件中,现在看起来像这样:
export { default as ExampleComponent } from "./ExampleComponent";
export { default as ExampleComponent2 } from "./ExampleComponent2";
...
我怎样才能做到这一点?
我看到了两种方法;一种动态方式,使您的库的用户代码更加复杂。您可以轻松地更改实现,另一个具有更多样板代码的实现,保持用户代码不变。
我没有测试他们在打包代码时关于 tree-shaking 的行为。
在用户代码中使用析构
这允许在您的主要组件导出文件中添加/删除内容,而不必担心库中的其他样板文件。可以轻松切换高阶组件 on/off。一个警告:用户代码需要使用解构来检索组件。
您的新 index.ts
文件看起来像这样,而我在同一目录中调用了您之前的 index.ts
文件 components.ts
:
import * as RegularComponents from "./components";
import withTestId from "./with-test-id";
const WithTestIdComponents = Object
.keys(RegularComponents)
.reduce((testIdComps, key) => {
return {
...testIdComps,
[key]: withTestId(RegularComponents[key])
};
}, {});
export default WithTestIdComponents;
要在您的应用程序代码中使用它:
import MyComponents from "./components/tested";
const { Component1, Component2, Component3, Component4 } = MyComponents;
这使用 default
导出使它看起来像是将所有组件放在一个地方,但由于您无法直接解构导出,因此您需要第二步才能从中获取正确的组件。
将样板添加到导出文件
由于库中有一个包含所有导出组件的 index.ts
文件,因此可以 import/rename 每个组件并使用 withTestId
及其名称重新导出它们:
import withTestId from "./with-test-id";
import { default as TmpComponent1 } from "./component1";
import { default as TmpComponent2 } from "./component2";
import { default as TmpComponent3 } from "./component3";
import { default as TmpComponent4 } from "./component4";
export const Component1 = withTestId(TmpComponent1);
export const Component2 = withTestId(TmpComponent2);
export const Component3 = withTestId(TmpComponent3);
export const Component4 = withTestId(TmpComponent4);
这样,进口可以像以前一样使用:
import {
Component1,
Component2,
Component3,
Component4
} from "./components";
我认为使用 index
文件已经是某种样板,而这种方法增加了它。由于用户代码不需要任何更改,我赞成这种方法。
在我们的一个项目中,每当我们生成新组件时,我们都使用自定义 takeoff 脚本为我们创建这种样板文件。
例子
这里有一个 code sandbox 来查看这两种方法。
我需要向我的 React 函数组件的 ALL 添加添加 [data-test-id]
属性的可能性以进行测试。为了实现这一点,我创建了 withTestId()
HOC,它将可选的属性 testId
添加到包装的组件中,当它被定义时,它将 [data-test-id]
添加到最终的 HTML.
所以当我像这样定义组件时:
<ExampleComponent testId="example" />
它returns:
<div data-test-id="example" />
我遇到的唯一问题是将它应用于每个组件,而无需将它单独包装在每个组件中。所以不要写这样的代码:
function ExampleComponent() { ... }
export default withTestId(ExampleComponent)
我想将所有导出内容打包到我的 index.ts
文件中,现在看起来像这样:
export { default as ExampleComponent } from "./ExampleComponent";
export { default as ExampleComponent2 } from "./ExampleComponent2";
...
我怎样才能做到这一点?
我看到了两种方法;一种动态方式,使您的库的用户代码更加复杂。您可以轻松地更改实现,另一个具有更多样板代码的实现,保持用户代码不变。
我没有测试他们在打包代码时关于 tree-shaking 的行为。
在用户代码中使用析构
这允许在您的主要组件导出文件中添加/删除内容,而不必担心库中的其他样板文件。可以轻松切换高阶组件 on/off。一个警告:用户代码需要使用解构来检索组件。
您的新 index.ts
文件看起来像这样,而我在同一目录中调用了您之前的 index.ts
文件 components.ts
:
import * as RegularComponents from "./components";
import withTestId from "./with-test-id";
const WithTestIdComponents = Object
.keys(RegularComponents)
.reduce((testIdComps, key) => {
return {
...testIdComps,
[key]: withTestId(RegularComponents[key])
};
}, {});
export default WithTestIdComponents;
要在您的应用程序代码中使用它:
import MyComponents from "./components/tested";
const { Component1, Component2, Component3, Component4 } = MyComponents;
这使用 default
导出使它看起来像是将所有组件放在一个地方,但由于您无法直接解构导出,因此您需要第二步才能从中获取正确的组件。
将样板添加到导出文件
由于库中有一个包含所有导出组件的 index.ts
文件,因此可以 import/rename 每个组件并使用 withTestId
及其名称重新导出它们:
import withTestId from "./with-test-id";
import { default as TmpComponent1 } from "./component1";
import { default as TmpComponent2 } from "./component2";
import { default as TmpComponent3 } from "./component3";
import { default as TmpComponent4 } from "./component4";
export const Component1 = withTestId(TmpComponent1);
export const Component2 = withTestId(TmpComponent2);
export const Component3 = withTestId(TmpComponent3);
export const Component4 = withTestId(TmpComponent4);
这样,进口可以像以前一样使用:
import {
Component1,
Component2,
Component3,
Component4
} from "./components";
我认为使用 index
文件已经是某种样板,而这种方法增加了它。由于用户代码不需要任何更改,我赞成这种方法。
在我们的一个项目中,每当我们生成新组件时,我们都使用自定义 takeoff 脚本为我们创建这种样板文件。
例子
这里有一个 code sandbox 来查看这两种方法。