AUTOR
Michal Hlaváč

Wrappovat či ne-wrappovat: Řešení udržitelnosti ve vývoji React aplikací 🌯

Při vývoji React aplikací často saháme po knihovnách třetích stran, které nám poskytují funkcionality od správy stavu až po vizuální komponenty. Tyto knihovny nám pomáhají urychlit proces vývoje, ale zároveň s sebou nesou množství závislostí, které nejsou přímo součástí naší aplikace.

V tomto článku si ukážeme, jak integrovat takové knihovny do architektury naší aplikace, aniž bychom ztratili přehlednost a snadno udržitelný kód.

Co je to wrap komponenty a k čemu slouží?

Wrap v kontextu React komponenty je přístup, který umožňuje zabalit existující komponentu jinou komponentou a modifikovat její chování nebo přidat funkcionalitu bez změny samotné komponenty. To umožňuje oddělení chtěných funkcionalit a zlepšuje znovupoužitelnost a udržitelnost kódu.

Jako příklad si můžeme vzít komponentu Button z knihovny Material UI (MUI). Originální komponenta Button poskytovaná knihovnou MUI nabízí jedenáct props, což může vést k řádově stovkám kombinací komponenty. V naší aplikaci však potřebujeme pouze 3 typy tlačítek: primární, sekundární, terciální.

V prvním scénáři se rozhodneme použít komponentu Button přímo z MUI. Vývojář bude muset každé tlačítko definovat manuálně pomocí kombinace props, což zvyšuje pracnost a vést k potenciální nekonzistenci a chybám.

Použití komponenty přímo z MUI

JavaScript

import Button from '@mui/material/Button';
import AddIcon from '@mui/icons-material/Add';

export const App = () => {
 return (
   <div>
     <Button variant="contained" color="primary" onClick={() => console.log('Primary button click ')}>
       I'm Primary
     </Button>
     <Button
       variant="outlined"
       color="secondary"
       startIcon={<AddIcon />}
       onClick={() => console.log('Secondary button click')}
     >
       I'm Secondary
     </Button>
     <Button variant="text" color="primary" onClick={() => console.log('Tertiary button click')}>
       I'm Tertiary
     </Button>
   </div>
 );
};

V druhém scénáři však použijeme wrap komponenty a omezíme tak její vlastnosti tak, aby komponenta nabízela pouze naše tři tlačítka. Vytvoření wrappovací komponenty nám přidá jednorázovou pracnost, ale po jejím vzniku si vývojář snadno vybere jednu z podporovaných možností a wrappovanou komponentu použije.

Wrapper komponenty z MUI

JavaScript

import Button, { ButtonProps } from '@mui/material/Button';

type CustomButtonType = 'primary' | 'secondary' | 'tertiary';

interface CustomButtonProps extends Omit {
 buttonType: CustomButtonType;
 startIcon?: ReactNode;
}

export const CustomButton: React.FC<CustomButtonProps> = ({ buttonType, startIcon, onClick, children, ...rest }) => {
 const getPropsByButtonType = (): { variant: 'contained' | 'outlined' | 'text'; color: 'primary' | 'secondary' } => {
   switch (buttonType) {
     case 'primary':
       return { variant: 'contained', color: 'primary' };
     case 'secondary':
       return { variant: 'outlined', color: 'secondary' };
     case 'tertiary':
       return { variant: 'text', color: 'primary' };
     default:
       return { variant: 'contained', color: 'primary' };
   }
 };

 return (
   <Button
     {...getPropsByButtonType()}
     startIcon={buttonType === 'secondary' ? startIcon : undefined}
     onClick={onClick}
     {...rest}
   >
     {children}
   </Button>
 );
};
Použití wrappované komponenty v aplikaci

JavaScript

import { CustomButton} from './customButton';
import { AddIcon } from '@mui/icons-material/Add'

export const App = () => {
 return (
   <div>
     <CustomButton buttonType="primary" onClick={() => console.log('Primary button click ')}>
       I'm Primary
     </CustomButton>
     <CustomButton
       buttonType="secondary"
       startIcon={<AddIcon />}
       onClick={() => console.log('Secondary button click')}
     >
       I'm Secondary
     </CustomButton>
     <CustomButton buttonType="tertiary" onClick={() => console.log('Tertiary button click')}>
       I'm Tertiary
     </CustomButton>
   </div>
 );
};

Udržitelnost aplikace a výhody wrappování

Nespornou výhodou tohoto přístupu je maintenance samotné komponenty.Vraťme se k našemu příkladu. Po roce provozu aplikace může dojít ke změnám na straně knihovny, a je nutné ji aktualizovat. Například, když knihovna MUI přejde z verze 4 na verzi 5, může dojít k zpětně nekompatibilním změnám.V prvním scénáři musíme upravit všechna místa, kde se Button používá, což může být zdlouhavé a náchylné k chybám.

V druhém scénáři musíme upravit pouze komponentu wrapu, což je mnohem efektivnější a méně náročné na čas.Tento přístup je mimořádně užitečný nejen pro jednu komponentu, ale i pro celou aplikaci postavenou na UI knihovně.

Každá taková komponenta může být použita na desítkách až stovkách míst v aplikaci. V případě údržby takové aplikace a povýšení verze MUI se bez použití wrapu dostáváme na nutnost provedení stovek až tisíců změn.

S použitím wrappování však musíme provést pouze omezený počet změn vycházející z počtu našich wrap komponent, což výrazně snižuje náklady na údržbu. Wrappování komponent třetích stran tak značně snižuje pracnost a náklady na údržbu aplikace, což přispívá k její dlouhodobé udržitelnosti a efektivitě ve vývoji.

Závěr

Wrappování komponent třetích stran je vždy tradeoff, do rozhodování vstupuje několik faktorů, například typ knihovny, se kterou pracujeme, rozsah použití komponenty z knihovny napříč aplikací nebo množství možností, které komponenta v knihovně poskytuje. Obecně stojí za úvahu wrappování komponent hlavně v případě UI knihoven nebo například knihoven pro práci s datem a časem.

Naopak je dobré se vyhnout wrappování v případě knihoven pro state management jako je Redux. V případě takových knihoven je lepší zaměřit se na správnou architekturu aplikace a přípravu její datové vrstvy.

Pro správné rozhodnutí, zda wrappovat či ne-wrappovat, si pojďme shrnout výhody a nevýhody tohoto přístupu.

Výhody

  • Snazší údržba kódu: Wrappování umožňuje lepší kontrolu nad funkcionalitami komponenty a usnadňuje úpravy a opravy v kódu.
  • Kontrola nad funkcionalitami komponenty: Wrappování umožňuje přidání nebo úpravu funkcionalit komponenty bez zásahu do původního kódu.
  • Snazší užití komponent: Wrappované komponenty mohou být jednodušeji použity a konfigurovány v rámci aplikace.
  • Nižší náklady na údržbu: Díky lepší organizaci a modularitě kódu mohou být náklady na údržbu aplikace sníženy.

Nevýhody

  • Větší počáteční náklady na výrobu wrapperů: Vytvoření wrappovacích komponent může vyžadovat dodatečnou práci a čas.
  • Nutnost dobré dokumentace existujících wrapper komponent: Aby bylo snadné použití wrappovaných komponent, je důležité mít k dispozici dostatečnou dokumentaci.

Závěrem, pokud si chcete udržet váš kód čistý, přehledný a snadno udržitelný, rozhodně nezapomeňte zvážit wrappování komponent ve vaší React aplikaci! Je důležité zvážit konkrétní situaci a potřeby vaší aplikace, aby bylo rozhodnutí co nejefektivnější a nejvhodnější pro daný případ.

Chci s vámi spolupracovat
Děkujeme za Vaši zprávu. Co nejdříve Vás budeme kontaktovat.
Nastala chyba při vyplňování formuláře. Zkuste jej vyplnit znovu, nebo se nám ozvěte přímo uvedený email.
Stáhněte si záznam zdarma
Děkujeme za Vaši zprávu. Co nejdříve Vás budeme kontaktovat.
stáhnout záznam
Nastala chyba při vyplňování formuláře. Zkuste jej vyplnit znovu, nebo se nám ozvěte přímo uvedený email.
Odebírejte náš newsletter
Děkujeme za Váš zájem.
Nastala chyba při vyplňování formuláře. Zkuste jej vyplnit znovu, nebo se nám ozvěte přímo uvedený email.

Přečti si taky