Использование Typescript Для Создания Простого Компонента Factory React

Простая фабрика — это довольно простой и распространенный шаблон проектирования, подробнее о котором и многом другом уже было описано в статья команда ВК .

Здесь вы узнаете о особенность машинописный текст называется «Дискриминированные профсоюзы» .

Мы сделаем завод типизированных компонентов.



Абстрактная проблема

Создать компонент (далее «заводской компонент»), который в зависимости от принимаемых им параметров будет возвращать подходящий для них компонент (далее «подкомпонент»).

При этом мы учитываем, что:

  • Компонент не должен принимать параметры, которые могут привести к его поломке.

  • Должна быть возможность расширить компонент, а именно добавить новый подкомпонент.
  • Он должен выполнять только вычисления, соответствующие возвращаемому подкомпоненту.

  • При использовании компонента должно быть понятно, какие параметры он принимает для каждого подкомпонента и что возвращает в ответ.


Настоящий вызов

Создайте компонент, который на основе переданных ему параметров рисует подходящую фигуру.



Моделирование

Смоделируем фигуры и параметры, необходимые для их рисования:
  • Прямоугольник – высота и ширина
  • Круг - радиус
  • Треугольник - три стороны
Каждая фигура имеет уникальные параметры, но кроме этого они могут иметь общий параметр — имя класса (css).



Использование Typescript для создания простого компонента Factory React

Фабричный компонент, который мы создадим, сможет принимать параметры для всех фигур, но для того, чтобы он возвращал нам соответствующую форму, мы укажем в параметрах тип фигуры.



Как это выглядит в Javascript

Давайте создадим абстрактные подкомпоненты (фигуры), поскольку их реализация в текущем контексте нас не интересует.
  
  
  
  
  
  
   

const Rectangle = ({className, width, height}) => .

; const Circle = ({className, radius}) => .

; const Triangle = ({className, sideA, sideB, sideC}) => .

;

Перейдем к заводской составляющей.



const Figure = ({ className, type, width, height, radius, sideA, sideB, sideC, }) => { switch (type) { case "rectangle": return height && width ? ( <Rectangle className={className} height={height} width={width} /> ) : null; case "circle": return radius ? <Circle className={className} radius={radius} /> : null; case "triangle": return sideA && sideB && sideC ? ( <Triangle className={className} sideA={sideA} sideB={sideB} sideC={sideC} /> ) : null; default: return null; } };

Краткое описание того, что в нем происходит. На основании переданного параметра типа мы определяем, что это за фигура.

Проверяем, получены ли все необходимые для этой фигуры параметры, если да, то рисуем фигуру.



Проблемы, возникающие при использовании javascript

  1. Разработчик, используя наш заводской компонент, не знает, какие параметры ему передать, чтобы получить нужную ему цифру.

    Ему придется повозиться с нашим кодом, чтобы понять, что к чему.

  2. Если параметры фигуры взяты от предка пятого поколения или, например, из хранилища redux, велика вероятность, что в какой-то момент параметры станут неверными и вам придется потратить много времени, чтобы понять, почему фигура не было нарисовано.

  3. Если вы передадите все параметры сразу, фабрика отрисует переданную в тип фигуру, используя соответствующие ей параметры, а остальные параметры будут игнорироваться.

    Это добавит неоднозначности в логику нашего компонента.

    Пример:

    Использование Typescript для создания простого компонента Factory React

    Использование фабричного компонента со всеми реквизитами одновременно

  4. Если мы передаем неверные параметры, мы сможем узнать об этом только просмотрев отрендеренный результат в браузере, так как IDE нам ничем не поможет.


Как это выглядит в машинописном виде?

Сначала давайте определим параметры, которые будут иметь все фигуры.

Это имя класса, как мы уже писали в главе «Моделирование».



interface IBaseFigure { className?: string; }

Давайте создадим те же абстрактные подкомпоненты, что и в версии javascript, но теперь с набором текста.



interface ICircle extends IBaseFigure { radius: number; } const Circle: React.VFC<ICircle> = ({className, radius}) => .

;



interface IRectangle extends IBaseFigure { width: number; height: number; } const Rectangle: React.VFC<IRectangle> = ({className, width, height}) => .

;



interface ITriangle extends IBaseFigure { sideA: number; sideB: number; sideC: number; } const Triangle: React.VFC<ITriangle> = ({className, sideA, sideB, sideC}) => .

; );

Пояснение к тому, что написано выше Мы создали интерфейс BaseFigure, а затем расширили его интерфейсами наших фигур, используя «extend».

Если мы определим новый параметр в BaseFigure, то он появится во всех интерфейсах, которые его расширяют. В интерфейсах мы также указали, какого типа должны быть параметры, className должен быть строкой и не является обязательным, а остальные параметры являются обязательными и должны быть числами.

Мы типизировали сами подкомпоненты, используя встроенный в React тип VFC, что означает «Функциональный компонент без дочерних элементов».

В целом такого «определения» будет достаточно для целей данной статьи.

Мы также стандартизируем нашу фабрику.



interface IFigureRectangle extends IRectangle { type: "rectangle"; } interface IFigureCircle extends ICircle { type: "circle"; } interface IFigureTriangle extends ITriangle { type: "triangle"; } type IFigure = IFigureRectangle | IFigureCircle | IFigureTriangle; const Figure: React.VFC<IFigure> = (props) => { switch (props.type) { case "rectangle": { return <Rectangle {.

props} />; } case "circle": { return <Circle {.

props} />; } case "triangle": { return <Triangle {.

props} />; } default: return null; } };

Сначала мы расширяем интерфейсы фигур, добавляя свойство типа с определенным значением.

Если для типа установлено это значение, то остальные параметры компонента будут определяться с помощью этого интерфейса.

На пальцах Объединяем (строка 13) такие интерфейсы и получаем единый интерфейс, где если параметр типа равен: прямоугольник, остальные параметры будут из IRectangle круг, остальные параметры будут из ICircle треугольник, остальные параметры будут из ITriangle Теперь, благодаря типизации, заводской компонент решил проблемы, которые присутствовали в js-версии.

Нам также больше не нужно проверять, все ли параметры получены.

Внутри «кейсов» мы можем узнать, какие параметры будут получены.



Использование Typescript для создания простого компонента Factory React

Просмотр параметров, принятых прямоугольником

Использование Typescript для создания простого компонента Factory React

Просмотр параметров, принятых треугольником При использовании сначала все реквизиты будут показаны нам во всплывающих подсказках.



Использование Typescript для создания простого компонента Factory React

Подсказки, когда тип не указан Но поскольку тип — обязательный параметр, его обязательно нужно будет указать.

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



Использование Typescript для создания простого компонента Factory React

Подсказки, когда указан тип

Использование Typescript для создания простого компонента Factory React

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

я ухожу ссылка на кодсанбокс , куда можно ткнуть и посмотреть результат вживую.



Заключение

Используя машинопись, мы получаем такие преимущества как:
  • Избавление от ненужных проверок на наличие параметров
  • Советы при разработке самого заводского компонента
  • Советы при использовании
  • Предупреждение от IDE, если вы передадите ей неверные параметры
В крупных и долгосрочных проектах это важные преимущества, которыми необходимо воспользоваться.

Теги: #JavaScript #frontend #react.js #typescript #react #печатать #шаблоны

Вместе с данным постом часто просматривают:

Автор Статьи


Зарегистрирован: 2019-12-10 15:07:06
Баллов опыта: 0
Всего постов на сайте: 0
Всего комментарий на сайте: 0
Dima Manisha

Dima Manisha

Эксперт Wmlog. Профессиональный веб-мастер, SEO-специалист, дизайнер, маркетолог и интернет-предприниматель.