Как обернуть каждый экспортируемый компонент с HO C? - PullRequest
3 голосов
/ 21 февраля 2020

Мне нужно добавить к ALL моих компонентов функции React возможность добавить атрибут [data-test-id] для тестирования. Чтобы добиться этого, я создал withTestId() HO C, который добавляет опциональную опору testId к обернутому компоненту, и когда он определен, он добавляет [data-test-id] к окончательному HTML.

Так что, когда я определяю компонент как:

<ExampleComponent testId="example" />

возвращает:

<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";
...

Как можно Я достиг этого?

1 Ответ

3 голосов
/ 21 февраля 2020

Я вижу два способа сделать это; Один динамический способ c, делающий пользовательский код вашей библиотеки немного более запутанным. вы можете легко изменить реализацию, а другую с немного большим количеством стандартного кода, сохранив код пользователя таким, какой он есть.

Я не проверял их поведение в отношении встряхивания дерева при объединении кода.

Использование уничтожения в коде пользователя

Это позволяет добавлять / удалять объекты из файла экспорта основного компонента, не беспокоясь о дополнительных шаблонах в вашей библиотеке. Компонент высшего порядка может быть легко включен / выключен. Одно предостережение: пользовательский код должен использовать деструктуризацию для извлечения компонентов.

Ваш новый файл 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 со всеми экспортированными компонентами в библиотеке можно импортировать / переименовывать каждый компонент и реэкспортировать их с 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 файлов уже является своего рода эталоном, и этот подход добавляет к нему. Поскольку пользовательский код не нуждается в каких-либо изменениях, я бы предпочел этот подход.

В одном из наших проектов мы использовали собственный сценарий взлет , чтобы создать для нас этот типовой пример всякий раз, когда мы генерируем новый компонент.

Примеры

Вот песочница с кодом , чтобы увидеть оба подхода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...