Как расширить интерфейсы атрибутов HTML при разработке компонентов React React? - PullRequest
3 голосов
/ 12 июля 2020

Я изучаю разум и очень рад этому. Что-то, что я часто делаю в коде реакции машинописного текста:

type Props = React.HTMLProps<HTMLButtonElement> & { foo: boolean }
const SuperButton: React.FC<Props> = (props) => <button {/* stuff with props */ />

В этом отношении я сообщаю своим пользователям как поставщик библиотеки компонентов, что эта кнопка расширяет обычные HTML атрибуты кнопки.

Как я могу express и расширить обычные html атрибуты компонентов в моих компонентах?

Я вижу, что причина явно не поддерживает распространение свойств: https://github.com/reasonml/reason-react/blob/master/docs/props-spread.md.

Я действительно вижу, что существует стратегия композиции: Как скомпоновать свойства компонента в привязках «причина-реакция»? , но не знаю, как совместить это с обычным набором компонентов HTML элементов.

Есть рекомендации? Спасибо!

1 Ответ

2 голосов
/ 12 июля 2020

Можно сделать что-то подобное, используя ReasonReact.cloneElement, как намекнул Амирали. Идея состоит в том, чтобы разделить свойства вашего компонента и свойства кнопки HTML на два отдельных параметра для вашего компонента, отрендерить кнопку и затем клонировать ее, одновременно добавляя дополнительные свойства кнопки.

Это На странице показан компонент, который инкапсулирует эту функциональность клонирования и внедрения:

module Spread = {
  [@react.component]
  let make = (~props, ~children) =>
    ReasonReact.cloneElement(children, ~props, [||]);
};

Теперь вы можете использовать этот Spread компонент для своего SuperButton компонента:

module SuperButton = {
  [@react.component]
  let make = (~foo, ~htmlButtonProps) =>
    <Spread props=htmlButtonProps>
      <button> (foo ? "YES" : "NO")->React.string </button>
    </Spread>;
};

Свойство htmlButtonProps будет содержать обычные HTML свойства кнопки, а отдельно foo - это свойство c вашего компонента. Компонент можно использовать следующим образом:

<SuperButton foo=true htmlButtonProps={"autofocus": true} />

Небольшое примечание по уборке: вам фактически не нужно определять модули с помощью ключевого слова module. При желании вы можете поместить их в отдельные файлы с именами Spread.re и SuperButton.re. Файлы Reason автоматически становятся модулями.

...