Přeskočit na hlavní obsah

Funkcionální paradigma: React a Redux

V poslední době se stalo funkcionální programování tématem, o kterém se hodně mluví. Z akademické sféry přešlo do praxe a jak se ukazuje, tak je to způsob, který je v určitých oblastech zajímavou alternativou, nahrazující imperativní přístup.

Dnešní článek bude zaměřen na to, co to vlastně je ten funkcionální přístup. I když na toto téma existuje spousty článků, tak často je vše popisováno příliš abstraktně, což zapříčinilo, že ne každý chápe, o co vlastně jde.

Abych byl schopen demonstrovat tuto problematiku, zvolil jsem si k tomu dvě knihovny, které jsou navrženy podle funkcionálního paradigmatu (alespoň z části).

Funkcionální programování

Přesná definice říká, že se jedná o deklarativní programovací paradigma, které chápe výpočet jako vyhodnocení matematických funkcí.

Samotný program si poté můžete představit tak, že je složen z funkcí, které volají další a další funkce a tím se postupně zjednodušují. Pokud bychom hledali jazyk, který je jednou z vlajkových lodí tohoto přístupu, nejspíše bychom skončili u LISPu či Haskellu.

Druhou důležitou vlastností je to, že funkce nevytváří vedlejší efekt. Ve výsledku to znamená, že na stejný vstup vždy dostávám stejný výstup a nemodifikuje žádný stav. Toto je jedna z důležitých vlastností, kterou se dá odlišit funkcionální a objektový přístup.

Lambda funkce

Abychom byli schopni deklarativního programování, budeme k tomu potřebovat jednu zásadní věc a tím jsou lambda funkce.

Při mém prvním studiu toho, co to vlastně lamba funkce jsou, jsem skončil s plnou hlavou různých teoretických a abstraktních pojmů a stále jsem nechápal, co to vlastně znamená.

Postupně jsem si vytvořil jednoduchou pomůcku, která mi osvětlila tuto problematiku. Tou pomůckou je, že funkci mohu přiřadit do proměnné a tím se proměnná stává funkcí.

Zkusím uvést příklad:

const hello = function(param) {
    return `Hello ${param}`;
};
console.log(hello('World'));

Na tomhle příkladě je vidět, že jsme vytvořili proměnnou s názvem "hello",  která je funkcí.

Příklad je vcelku jednoduchý, tak si ho pojďme trochu rozšířit:

const hello = function(param) {
    return `Hello ${param}`;
};
const helloFromLanguage = function(param) {
    return param('from Javascript');
};
console.log(helloFromLanguage(hello));

Nyní si můžeme všimnout, že jsme vytvořili druhou funkci s názvem "helloFromLanguage", která jako parametr přijímá funkci, kterou sám zavolá.

Nyní si ještě tento příklad přepišme pomocí arrow functions z ES6:

const hello = (param) => `Hello ${param}`;
const helloFromLanguage = (param) => param('from Javascript');
console.log(helloFromLanguage(hello));

To je vše. Lambda funkce a deklarativní programování je vcelku jednoduchá záležitost. Na rozdíl od imperativního přístupu se dá říct, že stále dokola vytváříme callbacky, které se reálně vykonají jinde, než na místě, kde jsme je definovali.

Javascript a funkcionální programování

Pokud bychom o javascriptu mluvili jako o funkcionálním jazyce, tak bychom to museli dát do uvozovek. Přesnější definicí je, že Javascript je hybridní jazyk, ve kterém můžete programovat jak objektově, tak funkcionálně.

I když se často porovnává, zda je lepší objektový či funkcionální přístup, tak si s tím nemusíme lámat hlavu. Osobně si myslím, že se tyto dva přístupy mohou kombinovat a tím těžit z obou paradigmat.

React a funkcionální přístup

Psát o tom, že je React skvělá knihovna pro psaní frontendu, je asi zbytečné. Všichni, co to jednou zkusí a pochopí jeho fungování, tak už nechtějí jinak. Je to stejné, jako když si zvyknete na MacBook, ... ale o tom až jindy :)

V Reactu naleznete několik míst, které "přiznávají" funkcionální přístup.

Pojďmě si několik těchto míst ukázat....

Stateless komponenty

Stateless komponenty jsou funkcí a ničím jiným. Díky tomu nemají žádný interní stav a pokud danou komponentu budeme volat se stále stejnými parametry, budete vždy dostávat stejný výstup.

Pojďme si ukázat jednoduchou komponentu:

interface Props {
    title: string;
}
export const InboxDetailBlock: React.SFC<Props> = ({title, children}) => (
    <fieldset>
        <legend><FormattedMessage id={title}/></legend>
        {children}
    </fieldset>
);

Komponenta přijímá jako vstup props s "title" a "children". Sama nic nemodifikuje, nemá interní stav a pokud jí předáme stejný vstup, vždy bude stejný výstup.

React props

Druhým místem, který lze zmínit jsou samotné props. Props jsou uvnitř komponenty v immutable stavu a tím pádem žádná komponenta nemůže způsobit vedlejší efekt v podobě mutace vstupu. K tomuto účelu slouží callbacky, kterými oznamujeme, že se v komponentě "něco stalo".

Rozšíříme náš příklad o ukázku s callbackem:

interface Props {
    title: string;
    onClick: () => void;
}
export const InboxDetailBlock: React.SFC<Props> = ({title, children, onClick}) => (
    <fieldset onClick={onClick}>
        <legend><FormattedMessage id={title}/></legend>
        {children}
    </fieldset>
);

interface PropsDetail {
}
export const Detail: React.SFC<Props> = () => (
    <InboxDetailBlock title="My block" onClick={() => console.log('Clicked!')}>
        <p>Hello world!</p>
    </InboxDetailBlock>
);

Zde můžete vidět, že komponenta "InboxDetailBlock" má událost na kliknutí na fieldset. Tato událost je směrem k rodiči oznámena pomocí callbacku. Tím se eliminuje nutnost mutace jakéhokoli stavu, který by tuto událost vykonal. Tomuto přístupu se říká "one way binding", kde se událost oznamuje pomocí callbacku a nikoli mutací.

Redux jako globální stav

Pokud jsme se bavili o tom, že metody nemají vedlejší efekt, který by mutoval stav, tak přesně tímto způsobem funguje i Redux. Redux, jakožto implementace Fluxu, vychází z jednoduché myšlenky, která říká: "Máme pouze jeden zdroj pravdy (globální stav) a pokud ho chceme měnit, tak musíme vytvořit jeho kopii, nikoli ho mutovat."
Ve funkcionálním paradigmatu bychom totiž globální stav neměli nikdy mutovat, ale pouze vytvářet jeho nové kopie. Tedy změna stavu je tvorba nového stavu.
V Reduxu k tomuto účelu slouží takzvané reducery, což jsou jednoduché funkce, které přijímají aktuální stav a payload akce. Návratovou hodnotou je poté nový stav.
Jednotlivé React komponenty, které jsou na Redux state navěšeny, poté automaticky reagují na změnu stavu.
Díky tomuto přístupu máte v čase vždy pouze jeden stav. S nadsázkou se dá říci, že pro debugování vám často stačí sledovat redux state a díky tomu víte v jakém stavu je celá vaše aplikace.
Pokud svou aplikaci programujete podle těchto pravidel, tak se vám nemůže stát, že by React či Redux vytvářel vedlejší efekty a čímž vám dost sjednodušuje život.

Závěr

Ve funkcionálním přístupu naleznete spoustu zajímavých témat, viz třeba monády. Cílem tohoto článku nebylo vysvětlit celou problematiku, ale pouze nastínit, jak to vlastně s tímto paradigmatem je.
Funkcionální a deklarativní přístup není spásou pro vše. Nicméně zde je krásně vidět, že existují oblasti vývoje, kde se tento přístup může hodit a ba co víc, může být i hodně prospěšný.
Existuje ještě jedna hezká ukázka a tou je implementace GraphQL, kde pomocí deklarativního zápisu, přes callback "resolve", je velice snadné, aby za GraphQL API byl jakýkoli zdroj, který by byl velice jednoduše měnitelný. Každopádně o GraphQL se ještě něco dozvíte v následujících článcích...

Komentáře

Populární příspěvky z tohoto blogu

Jak si v IT vydělat hodně peněz?

Na začátek by bylo dobré, abych objasnil samotný titulek, který může na někoho působit jako červený hadr. Článek nebude o obecných pravidlech, ale bude vyprávět můj vlastní příběh, na kterém vám zkusím ukázat, jak se dá docílit úspěchu, či alespoň správně nastartovat svojí vlastní kariéru v IT.

I když se z názvu článku dá dedukovat, že se vše bude točit kolem peněz, není tomu tak. Alespoň ze dvou třetin určitě ne. Ale to už předbíhám, pojďme to raději vzít hezky popořadě...

Kdybychom měli mluvit o roce 2017 jako o přelomové době, nejspíše to nebude pravda. I když pro někoho to může být rok plný úspěchů a štěstí v podobě narození zdravých dětí, svatby či první velké lásky, tak z pohledu lidstva se jedná o rok, který jen kopíruje předešlé a v oblasti technologií nás posouvá stejným tempem jako rok předtím.

Jsem naprosto přesvědčen o tom, že i když se současná doba tak nenazývá, tak prožíváme dobu, která jednou bude označena za revoluční, a to zejména díky vynálezu internetu, který je s…

Jak by se firmy neměly chovat k programátorům?

Každý, kdo pracuje v IT oboru, se jistě již setkal s různými „geniálními nápady“, od kterých si firma slibovala zlepšení produktivity či snížení nákladů. Ať už je to zavedení agilních principů, striktní kontrola práce či zavedení nové a skvělé metodiky, o které si „šéf“ přečetl včera na internetu. Jsou z toho skutečně tak nadšení i samotní vývojáři? A bude nový nápad fungovat?
K napsání tohoto článku mě navedly různé programátorské diskuze, kde si lidé stěžovali na firmu, kde pracují. Příklady, které zde uvedu, jsou z reálné praxe. Ať už jsem je zažil jako řadový programátor, či jako šéf týmu.
I když je poptávka po programátorech tak vysoká, že Vás headhunteři nahánějí i ve chvílích, kdy o to opravdu nestojíte, tak i přes to je mnoho lidí, kteří se bojí opustit svoje současné zaměstnání.
Čeho se nejčastěji bojíme? Je to samozřejmě nejistota, kterou si často omlouváme větami jako: „Tady mám své pohodlí, co když to jinde mít nebudu?“ nebo „I když mě to v práci štve a nebaví, tak mě ale…

Jak jsem technologicky postavil startup

Tento příběh pojednává o technologiích, nástrojích a vůbec o všem, co jsem potřeboval k tomu, abych byl schopen, postavit startup na zelené louce.

Každý správný příběh začíná stejně: "Jednou jsem...."

Kapitola první: Nápad
Jednou jsem se setkal s člověkem, který měl nápad na produkt, který se v průmyslu zatím nevyskytuje. I přes prvotní skepsi, kdy jsem si říkal: "Tohle už přeci dávno v průmyslu existuje, ne?", jsem došel ke zjištění, že nikoli.

Tím jsem se dostal ke svému prvnímu poučení. Průmysl je technologicky dost zabržděný. Osobně se domnívám, že těch důvodů, proč tomu tak je, je několik. Za prvé je to fakt, že většina lidí, kteří se pohybují v tomto odvětví jsou často konzervativní a za správné považují pouze léty osvědčené věci. Druhým důvodem je to, že jakákoli změna znamená riziko. Ať už z pohledu finanční ztráty tak i z pohledu stability výroby. No a třetím a nejzásadnějším důvodem je to, že ač zde máme spousty technologických vymožeností, narážíme na to,…