Zobrazují se příspěvky se štítkemTypescript. Zobrazit všechny příspěvky
Zobrazují se příspěvky se štítkemTypescript. Zobrazit všechny příspěvky

středa 18. července 2018

React a hrátky s TypeScriptem


V minulosti jsem se již několikrát zmiňoval, že používat JavaScript bez statických typů, je stejné jako jezdit na kole poslepu. Nemusí se Vám nic stát, ale také si můžete hezky ublížit. Jednou z variant, jak částečně předcházet problémům, je použití staticky typovaného jazyka. Už během psaní kódu je více viditelné, že "něco není v pořádku". TypeScript (dále jen TS) je jazyk, který nám k tomuto účelu může dobře posloužit.

Cílem dnešního článku jsou příklady, na kterých se pokusím demonstrovat vlastnosti jazyka, se kterými se lze setkat. Výčet určitě není kompletní, protože TS je velice sofistikovaný jazyk, který se nedá popsat ani jednou knihou.

Generické typy


Jak jednou řekl můj bývalý kolega: "Generické typy? To je ten zápis s kachníma zobákama, ne?" :)

Generické typy jsou součástí snad každého staticky typovaného jazyka. Generiky naleznete jak v Jave, C#, tak právě i v TS. Pokud v TS píšete, tak neexistuje téměř možnost, že byste se s generickými typy nesetkali.

Pojďme se podívat na jednoduchý příklad:
interface Props {
    firstName: string;
    lastName: string;
}
const User: React.SFC<Props> = ({firstName, lastName}) => (
    <div>
        {firstName} {lastName}
    </div>
);
const App = () => <User firstName={'Ales'} lastName={'Dostal'} />;

Zde je vidět, že je použita generika v React.SFC, což je typ, který definuje, že se jedna o React Stateless komponentu. Součástí tohoto typu je možnost uvést generický typ, tedy předem neznámý typ, který ovšem po deklaraci, bude kontrolován.

Zjednodušeně se dá říci, že pokud bychom v komponentě User definovali neznámý atribut, bude nám TS hlásit chybu:
Chybný atribut foo 
Jejich využití má největší přidanou hodnotu ve chvíli, kdy píšete kód, který má využití na více místech. Generické typy nabízí právě tu možnost, aby daný kód byl co nejvíce variabilní.

Od verze TS 2.9 je možné generické typy používat i přímo v JSX. Díky tomu je například snadnější typovat render props v Reactu.

Enum a string literal types


Často se dostáváme do situací, kdy je třeba definovat přesný výčet hodnot, které lze použít. 

Pojďme si rozšířit naší komponentu o novou vlastnost:
type UserType = 'admin' | 'guest';

interface Props {
    firstName: string;
    lastName: string;
    type: UserType;
}

const User: React.SFC<Props> = ({firstName, lastName}) => (
    <div>
        {firstName} {lastName}
    </div>
);
const App = () => <User firstName={'Ales'} lastName={'Dostal'} type={'admin'} />;

Nyní jsme přidali typ uživatele. Tím typem může být administrátor či host.

Pokud bychom do atributu type vložili jiný typ, tak TS zahlásí chybu:
Chybný typ uživatele
Kromě možnosti definovat výčet pomocí string literal types, tak je možné onen typ definovat i pomocí enum.

Příklad:
enum UserType {
    ADMIN = 'admin',
    GUEST = 'guest',
}
const App = () => <User firstName={'Ales'} lastName={'Dostal'} type={UserType.ADMIN} />;


Type queries a typeof


JavaScript disponuje klíčovým slovem typeof, který umí číst typy z jakéhokoliv objektu. Velice efektivně toho dá využít pro pro vytvoření typu z objektu.

Ano, zní to možná divně, ale pojďme se podívat na ukázku:
const initialState = {count: 0};

class User extends React.Component<Props, typeof initialState> {
    readonly state = initialState;

    handleOnClick = () => {
        this.setState(({count}) => ({count: count++}));
    };
    
    render() {
        const {firstName, lastName} = this.props;
        const {count} = this.state;
        return (
            <div onClick={this.handleOnClick}>
                {firstName} {lastName} | Count: {count}
            </div>
        );
    }
}

Komponentu User jsme přepsali do třídy a přidali State. Součástí toho je výchozí state, který komponenta očekává. V našem případě začíname na count = 0. Proto jsme využili toho, že podle nadefinovaného výchozí stavu, jsme vytvořili i daný typ State. Stejným způsobem bychom mohli použít typeof i v případě defaultních hodnot pro props.

Readonly a readonly


Nejen v Reactu bychom se měli snažit o to, abychom psali více funkcionálně. Současně s tím je důležité se zaměřit na immutable stav. Tedy najít způsob, jak zabezpečit, aby daná hodnota nešla přepisovat přímo, ale vždy se vytvářela pouze nová kopie.  K tomuto účelu můžeme využít readonly, který nám zajišťuje, že daný atribut v objektu bude immutable (alespoň z pohledu TS).

Pojďme na ukázku:
interface Props {
    readonly firstName: string;
    readonly lastName: string;
    readonly type: UserType;
}

const initialState = {count: 0};

class User extends React.Component<Props, Readonly<typeof initialState>> {
    readonly state = initialState;

    handleOnClick = () => {
        this.setState(({count}) => ({count: count++}));
    };

    render() {
        const {firstName, lastName} = this.props;
        const {count} = this.state;
        return (
            <div onClick={this.handleOnClick}>
                {firstName} {lastName} | Count: {count}
            </div>
        );
    }
}

V ukázce jsou použity dvě varianty. První variantou je definování u props, kde každý atribut je označen pomocí klíčového slova readonly. Druhou variantou je State, kde je použit typ Readonly. Pokud bychom nyní chtěli napřímo mutovat atributy Props či State, tak TS nám bude hlásit chybu, že daný atribut je readonly.

Pick


Další skvělou vlastností je typ Pick. Tento typ slouží k tomu, abychom si z předem definovaného typu, vytvořili nový typ, který bude obsahovat pouze ty atributy, které dopředu určíme.

Pojďmě opět na ukázku:
type UserType = 'admin' | 'guest';

interface UserDataQuery {
    readonly firstName: string;
    readonly lastName: string;
    readonly type: UserType;
}

interface Query {
    data: UserDataQuery;
    roles: string[];
}

interface Props extends Pick<Query, 'data'> {}

const initialState = {count: 0};

class User extends React.Component<Props, Readonly<typeof initialState>> {
    readonly state = initialState;

    handleOnClick = () => {
        this.setState(({count}) => ({count: count++}));
    };

    render() {
        const {data} = this.props;
        const {count} = this.state;
        return (
            <div onClick={this.handleOnClick}>
                {data.firstName} {data.lastName} | Count: {count}
            </div>
        );
    }
}

const App = () => <User data={{firstName: 'Ales', lastName: 'Dostal', type: 'admin'}} />;

Často se setkáváme s tím, že máme například z GraphQL vygenerovaný typový model, ale ten, na úrovni Query obsahuje všechny možné atributy, které lze získat. Zde se výborně hodí onen typ Pick, který nám vytvoří typ, který vychází z typu Query. Obsahovat bude pouze ty atributy, které si sami určíme. V našem případě tedy atribut data.

Omit


Pokud pomocí typu Pick můžeme definovat atributy, které nový objekt má obsahovat, jeho protějškem je typ Omit. Ten naopak umí definovat, které atributy nový typ obsahovat nebude.

Pojďme na ukázku (v ukázce je Omit použi z knihovny recompose):
interface UserQuestProps {
    data: Omit<UserDataQuery, 'type'>;
}

const UserGuest: React.SFC<UserQuestProps> = (props) => {
    return <User data={{...props.data, type: 'guest'}} />;
};

const App = () => (
    <div>
        <User data={{firstName: 'Ales', lastName: 'Dostal', type: 'admin'}} />
        <UserGuest data={{firstName: 'Ales', lastName: 'Dostal'}} />
    </div>
);

V tomto případě jsme vytvořili novou komponentu UserGuest, která ovšem umožňuje, že i když vychází ze stejného datového typu UserDataQuery, tak odstraňuje atribut type, který je přímo nastaven na hodnotu guest.

V tomto případě je na zvážení, zda by ona komponenta UserGuest, neměla být napsána spíše jako HOC (Higher-Order Component). Ale o tom až jindy :)

Závěr


Vybral jsem pár zajímavých vlastností TS jazyka, se kterými se lze často setkat a zároveň i věci, které nejsou až tak známé (viz Pick či Omit). Příště se zkusíme podívat na některé další vlasnosti.

Na závěr ještě celá ukázka našeho příkladu:
type UserType = 'admin' | 'guest';

interface UserDataQuery {
    readonly firstName: string;
    readonly lastName: string;
    readonly type: UserType;
}

interface Query {
    data: UserDataQuery;
    roles: string[];
}

interface Props extends Pick<Query, 'data'> {}

const initialState = {count: 0};

class User extends React.Component<Props, Readonly<typeof initialState>> {
    readonly state = initialState;

    handleOnClick = () => {
        this.setState(({count}) => ({count: count++}));
    };

    render() {
        const {data} = this.props;
        const {count} = this.state;
        return (
            <div onClick={this.handleOnClick}>
                {data.firstName} {data.lastName} | Count: {count}
            </div>
        );
    }
}

interface UserQuestProps {
    data: Omit<UserDataQuery, 'type'>;
}

const UserGuest: React.SFC<UserQuestProps> = (props) => {
    return <User data={{...props.data, type: 'guest'}} />;
};

const App = () => (
    <div>
        <User data={{firstName: 'Ales', lastName: 'Dostal', type: 'admin'}} />
        <UserGuest data={{firstName: 'Ales', lastName: 'Dostal'}} />
    </div>
);

středa 23. května 2018

React aplikace od začátku do konce

V poslední době jsme byli nuceni napsat více React aplikací, které vždy vychází ze stejného základu. Díky tomu jsem si uvědomil, že i když můžeme jednoduše provést setup čistého projektu, přeci jen je několik částí, které je nutné doplnit vlastním kódem. To mě nakonec dovedlo k myšlence, že jsem vzal čistý list papíru (gitu) a napsal example projekt, který slouží jako základní dev stack.

A tak jsem vytvořil "Aldu"

DEMO: https://alda.app
Git repozitář: https://github.com/ApiTreeCZ/alda

Co je cílem tohoto projektu?


Je to hlavně demonstrace toho, jak lze jednoduše napsat React aplikaci, která má snad vše, co je třeba. Díky tomu je zde přesah i do dalších oblastí jako je třeba nasazení do Kubernetes v Cloudu, CI/CD, apod.

Proč vlastní řešení?


Hlavním důvodem je, že díky rychlé evoluci JavaScript technologií se často dostáváme do stavu, kdy aktualizace jedné knihovny zapříčiní problémy v celém systému. Proto je snaha, aby tento projekt používal co nejaktuálnější knihovny a neustále dokola opravoval problémy, které vznikají s novými verzemi. Ano, svět JavaScriptu má i odvrácenou temnou stranu a tou je "jepičí život" některých knihoven a verzí.

Dalším důvodem je to, co již bylo zmíněno na začátku. Tedy využití Aldy pro start nových projektů.

A nakonec to nejdůležitější a tím je, že když chci propojit několik technologií, tak je velice malá pravděpodobnost, že najdu kompletní řešení. Vždy musím někde napsat nějakou část kódu, která nás nutí k tomu, abychom se stále probírali různými možnostmi, jak to vlastně udělat.

Co ten systém umí?


Tak hlavně je to React a to stačí :) .... Teď važně.

Jedná se React (už zase :)) aplikaci napsanou pomocí TypeScriptu. Celý systém je napsán přes Next.js, tudíž automaticky se jedná o isomorfní aplikaci, která podporuje server side rendering. Díky tomu jí lze nasadit na veřený web a není důvod se bát kvůli SEO a indexování od vyhledávačů.

Abychom trochu dodrželi štábní kulturu, tak v projektu je implementován TSLint a Prettier. Tedy kontrola na zápis kódu a zároveň automatické formátování podle předepsaných pravidel. Statická analýza kódu je v JavaScript světě nutností.

Celý systém je postaven na knihovně material-ui, která před pár dny vyšla oficiálně ve verzi 1.0. Díky tomu jsou CSS psány pomocí JavaScriptu a nakonec generovány jako css třídy.

Dále obsahuje Redux, do kterého si ukládá globálně důležité stavy. Díky tomu je zde redux-form, což je knihovna pro formuláře.

Pro lokalizaci je zde použitá knihovna react-intl, díky které je možné jednoduše používat překlady a to nejen textové, ale i číselné a datumové. Součástí toho je zde napsán vlastní systém generování výchozího jazyka a mergování do ostatních. V praxi to znamená, že když mám třeba výchozí angličtinu a přidám další jazyk, tak texty, které jsem v novém jazyce ještě neimplementoval, budou automaticky v angličtině.

Pro komunikaci s backendem je zde GraphQL a to v implementaci přes Apollo (sorry, ale Relay není ta cesta). Současně s tím je zde i malý backend server, který je vlastním GraphQL serverem. Vedle toho jsou zde navíc použity knihovny, které umožňují samotné GraphQL schéma generovat do TypeScriptu a tím pádem máte zadarmo celý API model a to jak na straně frontendu tak i backendu.

Další částí, která zatím není implementována, ale bude co nejdříve, je přihlašování pomocí JWT tokenu. Tedy autentizace přes login a heslo a autoriace přes JWT token.

Poslední důležitou součástí je příprava pro psaní testů pomocí knihovny Jest. Vedle toho je navíc integrace se službou Coveralls, která na základě výsledků testů provádí analýzu a říká nám, na kolik procent je náš kód pokrytý testy.

Nasazení do Cloudu


Pokud jsem na začátku zmínil, že jsem vytvořil základní stack pro vývoj React aplikací, tak je to jen 50% toho, co jsem udělal. Druhou částí je samotný způsob, jak aplikace funguje z pohledu DevOps.

Pokud to zjednoduším, tak Alda funguje tak, že pokud udělám přes GitHub nový release, tak se automaticky vytvoří Docker image, který se nasadí v Google Cloudu do Kubernetes clusteru přes Helm. Pokud nasadím aplikaci na novou doménu, tak automaticky vytvoří SSL certifikát přes Lets Encrypt. Je prostě cool, když nakonec jedním příkazem nasadíte celý ekosystém, který je škálovatelný. Jediné omezení je pak Vaše peněženka, ze které si musíte zaplatit tolik serverů, kolik uznáte za vhodné.

Celý proces nasazení je popsán v definici pro CircleCI. Ano, Alda používá CircleCI, což je jeden z nejlepších nástrojů pro CI/CD současnosti.

Plány do budoucna?


Na to je jednoduchá odpověď a tím jsou GitHub issues: https://github.com/ApiTreeCZ/alda/issues.

Jedna z věcí, kterou je třeba provést je samotný refactoring. Více implementovat vzory jako třeba: "Higher-Order Components" apod.

Pokud byste něco nového chtěli přidat, neváhejte poslat požadavek :)

Závěr


Hlavním důvodem, proč jsem chtěl sepsat tento článek není ani tak to, že bych chtěl naše řešení nějak propagovat, ale spíše pomoci ostatním, který řeší podobné problémy jako my. Ať už se jedná třeba o spojení material-ui s Next.js či o nasazení do Kubernetes.

Někdy příště popíši blíže celý projekt z pohledu samotného vývoje.

neděle 18. března 2018

Jak psát stabilní kód v JavaScriptu?

Pokud se rozhodnete, že v JavaScriptu napíšete větší část kódu, tak narazíte na to, že bez podpůrných nástrojů se z této cesty může stát peklo. Existuje velké množství vývojářů, kteří Vám řeknou, že JavaScript je bastl a nedá se v něm smysluplně napsat nic jiného, než pár drobností na rozhýbání webu. Opak je pravdou. V současné době je JavaScript nejuniverzálnějším jazykem na světě.

Je vcelku jedno, zda v JavaScriptu píšete aplikace typu backend, web, mobil, desktop, příkazy pro konzoli či třeba cloud funkce. Stále byste se měli snažit o to, abyste svůj kód zapsali tím nejlepším možným způsobem.

JavaScript se za posledních několik let výrazně změnil. Dostali jsme se do stavu, kdy existují dvě skupiny programátorů.

První skupinou jsou ti, kteří ignorují nové ECMAScript specifikace a JavaScript zapisují "starým způsobem". Do této skupiny často spadají lidé, kteří potřebují občas rozhýbat určitou část webu a JavaScript chápají jako jazyk, který přímo vykoná webový prohlížeč. O této skupině vývojářů se dá říci, že vlastně neumí v současném JavaScriptu programovat.

Druhou skupinou jsou vývojáři, kteří umí využít věci jako je Node.js, Babel, Typescript, apod. Kód v JavaScriptu zapisují v nových ECMAScript specifikacích a fakticky jsou schopni z tohoto jazyka často vytěžit maximum. Jedná se o naprosto jiný svět, než je tomu v případě první skupiny.

Abych Vám toto předal trochu více exaktněji, podívejte se na následující příklad, který ilustruje rozdíl mezi první a druhou skupinou:
// prvni skupina
function oldWay(options) {
    return {
        name: options.name,
        hello: function () {
            return 'Hello ' + options.name;
        }
    }
}

// druha skupina
const newWay = ({name}) => ({name, hello: () => `Hello ${name}`});

console.log(oldWay({name: 'Old way'}).hello());
console.log(newWay({name: 'New way'}).hello());

Tento kód je založen na využití arrow functions, string interpolation a destructuring assignment. Věřte, že je to jen část vlastností, které nové ECMAScript specifikace nabízí. Teď ruku na srdce, pokud je zde čtenář té první skupiny, poznal by, že ten druhý zápis ve výsledku dělá tu samou věc? Na JavaScript se dá koukat jako na dva jazyky. Na jazyk před ECMAScript 6 a jazyk s ECMAScript 6 a vyšší.

Ale pojďme zpět. Jak zajistit to, abychom v JavaScriptu byli schopni psát stabilní kód, který se nám nerozsype s novou posilou v týmu či tím, že někdo bude psát "starým" a někdo "novým" způsobem?

Airbnb JavaScript Style Guide

První věcí, kterou by každý JavaScript programátor měl začít je, že si přečte a osvojí si style guide, tedy zápis JavaScript kódu. K tomtu účelu se výborně hodí následující příručka Airbnb JavaScript Style Guide.
Dokud si toto neosvojíte, těžko se můžete považovat za seniornějšího JavaScript programátora.

Typescript / Flow

Pokud to s JavaScriptem myslíte skutečně vážně, určitě byste se měli snažit o to, abyste tento jazyk obohatili o statickou typovou kontrolu. Jelikož je JavaScript dynamicky typovaný jazyk, tak v případě, že se Vám projekt v JavaScriptu rozšíří, tak bez typové kontroly je jakýkoli refactoring roven ruské ruletě. Osobně preferuji Typescript a důvody proč, jsem sepsal v článku Proč právě Typescript.

Typescript strict mode

Součástí Typescriptu je i možnost nastavení striktního módu. Toto nastavení se jmenuje přímo "strict". Co se díky tomutu módu vše zapne, najdete v manuálu: https://www.typescriptlang.org/docs/handbook/compiler-options.html

ESLint / TSLint

Další nezbytnou součástí je ESLint (v Typescriptu TSLint). Linting, nebo-li "lustrování" kódu slouží k tomu, aby Vám nadával za to, že jste kód nezapsali zrovna tím nejlepším způsobem. Například Vám řekne, že jste napsali function, místo toho, abyste použili arrow function, že jste string zapsali ve špatných uvozovkách, že jste překročili limit počtu znaků na řádku, apod.
I když možná budete tento linter na začátku nenávidět, tak věřte, že je to dočasné. Časem totiž poznáte, že je to velice dobrý sluha. Dá se říci, že Vás naučí správně zapisovat JavaScript kód.

Prettier

Dalším skvělým pomocníkem je Prettier. Tento nástroj slouží k tomu, že za Vás automaticky formátuje kód. K čemu je to vlastně dobré?
Osobně pracuji tak, že když píšu kód, tak automaticky stále spouštím dvě základní operace nad kódem: "Format code & Optimize imports". Dělám to tak už roky a jsem přesvědčen, že by toto měl dělat každý vývojář. Každý moderní vývojový nástroj (Atom, WebStorm, Visual Studio Code, apod) má tyto dvě operace k dispozici.
Ve chvíli, kdy pracuji na projektu, kde je více lidí, tak bez automatického formátu vzniká problém. Co dokáže naprosto otrávit je, když automaticky formátujete kód jen v editoru a najednou uděláte změny i tam, kde jste vůbec nepracovali. Git Vám poté hlásí, že poslední změnu na daném řádku jste udělali Vy a přitom to není vůbec pravda.
První variantou je, že všem vývojářům přikážete, že musí používat jedno IDE a jeden styl formátování. A věřte, to je to poslední, co chcete dělat. Ne každý chce třeba psát kód v IntelliJ IDEA. Proto zde máme Prettier. Nástroj, který za nás určí pravidla a vy se jim automaticky přizpůsobíte, ať už píšete v poznámkovém bloku či třeba v Atomu.
Druhou důležitou vlastností je to, že Prettier Vám formátuje kód tak, aby správně doplnil závorky, středníky, atd, podle jasně definovaného style guide.

Integrace TSLintu a Prettier s Gitem

Nyní se pojďme podívat na to, jak využít TSLint a Prettier při práci s Gitem. Berme v potaz, že již máte projekt v Gitu. Projekt je v Typescriptu a jedná se o React aplikaci.

Nejprve do projektu přídáme závislost na tslint a tslint-react:
npm i -D tslint tslint-react

Poté do projektu přidáme soubor tslint.json:
{
  "extends": [
    "tslint:recommended",
    "tslint-react"
  ],
  "rules": {
    "max-line-length": [
      false,
      160
    ],
    "semicolon": [
      true,
      "always",
      "ignore-bound-class-methods"
    ],
    "quotemark": [
      true,
      "single",
      "jsx-double"
    ],
    "member-ordering": [
      true,
      "variables-before-functions"
    ],
    "ordered-imports": false,
    "interface-name": false,
    "object-literal-key-quotes": [
      true,
      "as-needed"
    ],
    "object-literal-sort-keys": false,
    "no-object-literal-type-assertion": false,
    "no-empty-interface": false,
    "jsx-no-multiline-js": false,
    "jsx-boolean-value": false,
    "member-access": false
  }
}

Do package.json stačí přidat následující skript:
"scripts": {
    "tslint": "tslint -c tslint.json 'src/**/*'"
}

A poté spustit:
npm run tslint
Hlásí Vám tslint chybu? Pokud ano, tak nezbýbá, než ony chyby opravit :)

Nyní pojďme přidat prettier:
npm i -D husky prettier pretty-quick
Současně s knihovnou prettier nainstalujeme knihovnu husky, která slouží k tomu, že vytvoří git hook.

Dále v projektu vytvoříme soubor .prettierrc.json:
{
  "printWidth": 160,
  "tabWidth": 4,
  "parser": "typescript",
  "singleQuote": true,
  "bracketSpacing": false,
  "trailingComma": "all",
  "arrowParens": "always"
}

Jelikož použijeme pretty-quick pro provedení automatického formátování, je třeba definovat soubor .prettierignore, ve kterém určíme adresáře a soubory, které z automatického formátovaní chceme vynechat:
.circleci/
.next/
dist/
package.json
package-lock.json

Poté, co máme základní konfiguraci hotovou, nezbývá, než obohatit náš package.json:
"scripts": {
    "tslint": "tslint -c tslint.json 'src/**/*'",
    "precommit": "pretty-quick --staged && npm run tslint"
}
A nyní stačí zkusit provést commit do gitu :)

Toto řešení je postavené na tom, že používáte Git. Před tím, než se provede samotný commit do Gitu, tak se nejprve spustí formát kódu a poté se překontroluje pomocí TSLintu. Pokud máte něco špatně, commit se neprovede. Pokud Vám nevyhovuje precommit, můžete využít i možnost prepush, tedy před tím, než se provede push do remote git repozitáře. Nicméně výsledkem je, že se Vám do společného Git repozitáře vždy dostane pouze kód, který je spravné formátovaný a zkontrolovaný pomocí linteru.

Kromě Git hooku je určitě vhodné, abyste toto provedli ještě v CI. Tedy ve vašem nástroji na continuous integration. V našem případě se jedná o CircleCI, kde pouze spustíme samotný příkaz npm run tslint a tím zajistíme, že před nasazením na server nemáme v kódu něco špatně.

Závěr

Zajistit štábní kultruru v JavaScript projektech není složitá záležitost. Celé je to pouze o tom, že čím déle budete věci jako je TSLint či Prettier ignorovat, tím víc práce v budoucnu budete mít.
Také je dobré zmínit, že nelze nekriticky spoléhat na tyto nástroje. Stále je pouze na Vás, zda kód, který napíšete je nakonec funkční. Nejsou to nástroje, které Vás například zbaví nutnosti psát unit testy.
A co vy? Používáte některé ze zmíněných nástrojů?

středa 31. května 2017

Proč právě Typescript?

Pokud to někdo s vývojem v javascriptu myslí vážně, měl by hledat způsob, jak nejlépe napsat udržitelný kód.

Díky vlastnostem, které přinesly ES5 a ES6, máme již k dispozici jazyk, který se netváří tak nepřátelsky.

Nicméně, stále existuje jedna věc, kterou javascript nenabízí a která je u většího projektu dost zásadní. Tou vlastností je typovost.

Proč bychom měli chtít typy v javascriptu?


Odpověď je vcelku jednoduchá. Z důvodu udržitelnosti kódu.

Představte si situaci, že máte projekt, kde chcete provést refactoring či změnu v modelu aplikace. V případě, že váš projekt nemá typy, budete se muset spolehnout pouze na špičkově napsané testy, které vám prozradí, zda jste v kódu něco nerozbili :)

Pojďme si udělat malou ukázku.

Máme entitu uživatele, kterou zobrazujeme v tabulce. Zjednodušený kód by vypadal asi následovně:

const users = [
    {id: 1, firstName:  'Ales', lastName: 'Dostal', roles: ['admin']},
    {id: 2, firstName:  'Petr', lastName: 'Novotny', roles: ['operator']},
];

Nyní toto pole zobrazíme v tabulce:

users.map((row) => (
    <tr>
        <td>{row.firstName} {row.lastName}</td>
        <td>{row.roles.join(', ')}</td>
    </tr>
));

Tady je svět asi v pořádku, ale co nastane, když budete potřebovat provést změnu, která spočívá v tom, že atribut roles budete muset zahodit a říci, že uživatel může obsahovat pouze jednu roli? Atribut roles se přejmenuje na role a přijímat bude pouze jeden řetězec, ale nikoli pole.

const users = [
    {id: 1, firstName:  'Ales', lastName: 'Dostal', role: 'admin'},
    {id: 2, firstName:  'Petr', lastName: 'Novotny', role: 'operator'},
];

Co zbytek vašeho kódu?
Jen velice těžko budete dohledávat, zda objekt user obsahuje ty správné atributy, se kterými pracujete v metodě map, pro vypsání řádku tabulky. Javascript se bude tvářit, že je vše v pořádku a problém zjistíte až za běhu. A to skutečně nechce přeci nikdo.

Pojdmě náš kód obohatit o typovost pomocí Typescriptu. První věcí, kterou musíme udělat je, že si vytvoříme definici typu User.

interface User {
    readonly id: number;
    readonly firstName: string;
    readonly lastName: string;
    readonly roles: string[];
}

Nyní řekneme, že proměná users je typu pole User.

const users: User[] = [
    {id: 1, firstName: 'Ales', lastName: 'Dostal', roles: ['admin']},
    {id: 2, firstName: 'Petr', lastName: 'Novotny', roles: ['operator']},
];

A nyní, když budeme chtít změnit model, změníme definici.

interface User {
    readonly id: number;
    readonly firstName: string;
    readonly lastName: string;
    readonly role: string;
}

V té chvíli nám bude kompilátor Typescriptu vracet chybové hlášení, které nás upozorní, že máme špatně inicializovanou proměnou users a současně, že v metodě map předpokládáme, že existuje atribut roles, které je pole.

Teď si vemte tuto malou ukázku a vynásobte jí třeba 100x krát. Opravdu chcete ještě stavět projekt bez typů?

Co je tedy ten Typescript?


Typescript je jazyk, který byl představen v roce 2012 Microsoftem. V podstatě vychází z jednoduché myšlenky, která říká: "Pište klasicky v javascriptu, jen k němu přidejte typy".
I když Typescript má i další vlastnosti, které javascript nenabízí, tak jeho hlavní přínos je právě v oné přidané typovosti.

V praxi to vypadá tak, že píšete soubor, který si označíte jako typescript soubor (většinou pomocí přípony *.ts) a poté tento soubor zkompilujete kompilátorem Typescriptu. Výsledkem je javascriptový soubor, který je v dané ES specifikaci. O tom, do jaké specifikace chcete soubor kompilovat je na vás.

Více se o typescriptu můžete dozvědět z oficiálního webu.

Typescript není Java


Často se setkávám s tím, že lidé k Typescriptu přistupují jako k Jave. I když zde najdete spoustu společných vlastností, je dobré mít stále na paměti, že Typescript funguje jinak.
Jedním z hlavních rozdílů je to, že Typescript své typy porovnává na úrovni struktury.

Uveďme si příklad:

interface Cat {
    name: string;
}

interface Dog {
    name: string;
}

const cat: Cat = {name: 'Mourek'};
const dog: Dog = cat;

Proč tomu tak je?

Jde o to, že Typescript sice má typy, ale představte si, že jsou to stejně jen jakési flagy, které Vám mají pomáhat při psaní kódu. Poté, co se daný soubor zkompiluje do javascriptu, tak typy jsou odstraněny a pracuje se pouze s JSONem.

Další věcí je, že chyby, které Vám kompilátor Typescriptu bude hlásit můžete často ignorovat. Výsledný kód bude funkční, dokud…

Příkladem je také třeba klíčové slovo readonly, kterým pokud označíte atributy daného typu, tak tím říkáte, že je nelze přímo přepsat. Nicméně, pokud to v kódu ignorujete, tak výsledkem bude validní javascript, protože ten žádné klíčové slovo readonly nezná.
Proto budťe obezřetní, při psaní v Typescriptu. Pořád je třeba mít na paměti, že je to javascript, který si jen typuji.

Další možnosti, jak typovat javascript


Kromě Typescriptu zde existuje ještě jedna varianta, která ve své podstatě dělá to samé (i když jiným způsobem). Tou variantou je FlowType či označováno jen jako Flow. 

Flow je statická typová kontrola, kterou vytvořili lidé z facebooku. Na rozdíl od Typescriptu, je Flow méně invazivní a jedná se v podstatě pouze o "type check", kdežto v případě Typescriptu to je kompletní kompilace.

A proč tedy Typescript a ne Flow?


Tuto otázku jsem si pokládal dost často. Přeci jen, vždy máme touhy pokukovat po alternativách a hledat, zda někdo nemá ten "trávníček o něco zelenější". Já osobně jsem do Typescriptu šel ze dvou hlavních důvodů.

1. Typescript je tady déle a používá ho více knihoven
Tím, že byl první, tak z toho dodnes těží. Týká se to zejména knihoven, které když stáhnete z NPM, často se setkáte s problémem, že daná knihovna nemá definované typy. A pokud ano, je větší pravděpodobnost, že typy budou pro Typescript, nikoli pro Flow.

2. Angular 2
Ač jsem zastánce Reactu a Angular vnímám spíše jako ukázkovou cestu, kterou nejít, dá se zde mluvit o tom, že Typescript je nejvíce zpopularizován právě Angularem 2, který tento jazyk zvolil jako výchozí. Microsoft vytvoří jazyk a Google framework, který ho evangelizuje. Ironie, že? :)

Závěr


Už jste začali používat typy v javascriptu? :)

pondělí 29. srpna 2016

React JS: Jak začít?

V předchozím příspěvku jsem se věnoval drobnému porovnání React a Angular 2. Nyní se pojďme podívat na to, jak začít....

Mnoho nových termínů a technologií

Před tím, než se pustíte do vývoje webové aplikace pomocí Reactu, dostane se Vám do ruky nepřeberné množství technologíí, které s tímto vývojem souvisí.
Jak už jsem zmiňoval, tak i přesto, že Angular 2 nabízí možnost "all in one", tak ani tam se nevyhnete tomu, že se budete muset naučit pracovat s několika novými "pojmy".
Myslím si, že právě to, že postavit funkční dev stack je vcelku alchymie, dochází k tomu, že mnoho lidí skončí dřív, než vůbec začne.
K tomu, jak správně začít se dozvíte z tohoto článku.

React DEV stack

Tento DEV stack vychází z mého vlastního návrhu. Inspiraci jsem čerpal jak z diskuzních fór typu stackoverflow.com, tak i z různých blogů na toto téma. Pojďme to tedy vzít postupně....

https://www.npmjs.com/

I když je React možné provozovat tak, že do index.html vložíte odkaz na js soubory Reactu, tak počítejte s tím, že tento způsob je dobrý maximálně na prototypování, tedy na vyzkoušení si, jak vlastně psát v Reactu komponenty.
V budoucnu se dostanete do fáze, kdy budete potřebovat řešit i jiné knihovny, verzování, spouštění skriptů, apod. K tomuto účelu slouží právě NPM, což není nic jiného, než package manager pro javascript.
Pomocí NPM si nalinkujete vše, co Vaše aplikace bude potřebovat. Ať už je to bootstrap, jQuery či knihovny typu Redux, apod.
NPM se definuje pomocí souboru package.json. V něm definujete jak dané knihovny, tak i samotné skripty, které chcete spouštět. Poté již stačí jen v daném adresáři napsat: "npm install" a všechny Vaše knihovny se automaticky stáhnou a nainstalují do adresáře node_modules.
Spouštění skriptů se provádí pomocí "npm run xxx". Kde za xxx dosadíte název z package.json.

Webpack

Bohužel pouze s NPM si nevystačíte. Sice už víte jak správně přidávat nové knihovny, ale stále před Vámi bude problém ohledně toho, jak správně aplikaci sestavit, jak spustit debug, jak vytvořit produkční build, apod. K tomuto účelu slouží právě Webpack. 
Existují i varianty typu Gulp či Grunt, nicméně věřte, že právě Webpack všechny tyto alternativy překonává.
Důvodem proč, je to, že pokud budete ignorovat Webpack a půjdete cestou třeba Gulpu, Vaše aplikace bude obsahovat šílený Gulp skript, kterým budete ovládat jednotlivé potřeby Vaší aplikace.
Webpack na to jde jinak. Pomocí modulů.
Napadá mě jedna hezká synergie: Gulp = Ant, Webpack = Maven :)

Typescript

Pokud čekáte, že se javascriptové aplikace píší v čistém javascriptu, musím Vás zklamat. Téměř nikdo to nedělá. Tedy alespoň ne ti, kteří to myslí skutečně vážně :)
Asi by se našlo hodně lidí, kteří by předchozí větu zpochybnili a jistě by měli pravdu. Mnoho lidí píše v javascriptu, ale ne v tom, který je aktuálně podporován většinou prohlížečů. Zkusím to trochu více rozvést....
Javascript spadá do specifikace ECMA Scriptu. ECMA Script není javascript a javascript není ECMAScript. ECMAScript je specifikace :)
V současné době je ve vývoji verze 7. I když je verze 6 už více jak rok stará, tak bohužel většina webových prohlížečů stále na 100% nepodporuje všechny její vlastnosti.
Jelikož rádi zkoušíme nové věci a rádi bychom využívali nové možnosti, které daný jazyk nabízí (a v případe specifikace ECMA Scriptu, to jsou skutečně zajímavé vlastnosti), tak hledáme způsob, jak je využít již teď.
Proto mnoho vývojářů začalo používat transformaci, kde aplikaci napíší ve specifikaci ECMA 6 a převedou ji do verze ECMA 5, se kterým si většina webových prohlížečů již poradí.
K tomuto účelu výborně slouží Babel. 
Touto cestou se vydal také React a většinu aplikací, které naleznete na github.com, jsou napsány právě pomocí Babelu.
Bohužel stále zde existuje jeden velký neduh a to je typovost. Psaní v ECMA 6 je sice výrazně lepší varianta, nicméně není to ideální volba.
Microsoft přišel s vlastní specifikací jazyka, který se jmenuje Typescript. Typescript je například výchozím jazykem pro Angular 2. Důvod, proč Google zvolil technologii Microsoftu je to, že i když je Typescript vlastní jazyk, je plně kompatibilní s ECMA specifikací.
Jinými slovy, to znamená, že v typescriptu můžete psát jako v javascriptu a on bude stále validní.
Výhoda Typescriptu je zejména v tom, že jde za hranice ECMA Scriptu 6. Nabízí totiž typovost, která Vám bude zaručovat lepší konzistenci celého projektu.
Jedinou nevýhodou, která je s Reactem spojena, je to, že React na začátku zvolil Babel a proto je většina ukázek práve s ECMA 6 a nikoli v Typescriptu. Nicméně není třeba se bát. Psát pomocí Typescriptu v Reactu je pohodlné a osobně jsem nenarazil na problém, který by neměl řešení. Pro představu, jak psát pomocí v Reactu Typescriptu je zde: React a Typescript. 
Doporučení na závěr: NIKDY NEPIŠTĚ ČISTÝM JAVASCRIPTEM. Pokud Vám Typescript z nějakého důvodu nevyhovuje, zvolte alespoň transformaci pomocí Babelu. Nicméně Typescript je nejlepší volba, kterou můžete nyní zvolit.

Redux

O reduxu jsem psal v minulém přispěvku. Hned po té, co ovládnete React, implementujte Redux. Důvody, proč zvolit Redux je jednoduchá. Budete mít stav své aplikace pod kontrolou.

React Router

Samotnými komponenty Reactu si v aplikaci skutečně nevystačíte. Pokud hledáte, jak správně routovat, existuje jasná volba. 
Možná Vás napadne myšlenka, proč není React Router součástí Reactu. Důvodem je to, že React Router slouží pro webové aplikace a samotný React neslouží jen pro psaní webů. Existuje zde totiž možnost, psát v Reactu i mobilní aplikace. K tomuto účelu slouží React Native. Proto je React Router jako vlastní knihovna a není jeho součástí. React Native je zajímavá alternativa, jak psát mobilní aplikace a v budoucnu o této technologii jistě něco napíši.


Redux Thunk

Pokud použijete Redux, tak se dostanete k jedné zásadní otázce. Tou je, jak se poprat s asynchronním zpracováním. Redux Thunk nedelá nic jiného, než to, že Vám v rámci akce umožňuje získat dispatch instanci, díky které, můžete vyvolat akci i uvnitř asynchronní metody.
To je na Reduxu a Reactu skvělé. Napadlo Vás někdy, že například Facebook umožňuje ukázat návrh bloku, do kterého se vykreslí komentáře, aniž by dané komentáře byly ze serveru již načteny?
Funguje to tak, že například řeknete, že chcete ze serveru stáhnout další položky. Reduceru pošlete informaci o změně a díky tomu se UI komponenta může začít měnit. Nicméně, vedle toho se ptáte serveru a čekáte na skutečnou změnu, která až Vám přijde, tak jí přepíšete v reduxu, pomocí stejného reduceru :)

Fetch

Poslední věcí, o které zde napíší je whatwg-fetch. Jak už jsem minule zmiňoval, tak React neobsahuje knihovnu na volání Vašeho REST (GraphQL) server API. K tomuto účelu můžete využít několik knihoven. Jedna je samozřejmě i přímo v jQuery. Osobně jsem na doporučení zvolil Fetch, což je knihovna doporučována snad všemi.
Fetch se snaží držet standardů a navíc její použití je velmi jednoduché.
V budoucnu se snad dočkáme i toho, že samotný ajax call půjde udělat přímo díky podpoře webových prohlížečů. Firefox a Chrome již dnes totiž podporují možnost window.fetch.

Závěr

Toto byl výčet těch nejdůležitějších technologií a knihoven, které při tvorbě webové aplikace Reactem lze využít. Osobně mám pár dalších technologií, které jsou již dost okrajové a mohou se měnit na základě požadavků na Vaší aplikaci. Tento výčet je ovšem základ, který bych použil vždy, když bych se dostal k vývoji webové aplikace Reactem.
Ještě bych rád zmínil jedno doporučení. Pokud začnete hledat knihovny, které by Vám pomohly při tvorbě aplikace, byl bych obezřetný, abyste svůj projekt příliš nezahltili knihovnami třetích stran, které jsou často tvořeny jednou osobou. Na každý problém totiž v NPM naleznete knihovnu, která by Vám mohla pomoci. Bohužel je problém v tom, že jich je příliš mnoho a některé mají jepičí život. Buďte skutečně opatrní a spíše se koukejte po tom, zda je daná knihovna skutečně využívána a například díky githubu bych si zkontroloval, zda je aktuální a někdo na ní pracuje.

středa 10. srpna 2016

Vývoj webových aplikací: React a Angular 2

Článek je založen na základních zkušenostech Reactu a Angularu 2, ve kterých jsem napsal jednoduchou CRUD aplikaci s reportingem a autorizací. U obou aplikací byl použit stejný backend (Spring REST, JPA repository).

K napsání tohoto příspěvku mě donutila skutečnost, že jsem se v poslední době zaměřil na frontendové technologie a chtěl si vyzkoušet několik cest, které mohou vést k úspěšnému cíli.

V současné době je velmi populární tvorba tzv "single page" webových aplikací, které jsou vykonávány javascriptem na straně klienta.

Doba pokročila a kromě tzv single page aplikací se také objevilo něco, čemu se říká isomorfní aplikace. Tomuto tématu se věnovat nechci, nicméně je to další evoluční krok, který v podstatě říká, že část javascriptové aplikace běží na serveru. Lépe to vystihuje následující článek: What is an isomorphic application?

Ale zpět k single page aplikacím. Proč jsou vlastně tak populární a co mi to přináší z pohledu vývoje?

Tak zejména je to fakt, že webovou část nevnímám jako prezentační vrstvu tvořenou pomocí html, ale fakt, že daná webová stránka je aplikací. Tedy umí pracovat s událostmi a její jednotlivé části jsou měněny bez nutnosti znovunačítat celý kontext či se ptát serveru na změnu. Celá stránka je kontext, ve kterém pracuji a ve kterém provádím i například routování (přechod na jiné stránky, které jsou v podstatě jen změny v blocích).

Nespornou výhodou je to, že vše je zpracováváno na straně klienta, čímž pádem striktně rozděluji aplikaci na backend a frontend. Backend již nemusí nést tolik informací o prezentační vrstvě a soustředí se pouze na svou část.
Na rozdíl od toho je frontend schopný fungovat bez backendu a je velice jednoduché postavit webovou aplikaci bez backendu. Představte si situaci, kdy díky obřímu JSON souboru pošlete do aplikace celý její model a jste schopni ji ukázat zákazníkovi, aniž byste museli napsat čárku v backend systému.

Další nespornou výhodou je to, že většina frameworků, které se pro single page aplikace používají jsou komponentově orientované. Tedy umožňují vytvářet znovupoužitelné komponenty a na konci toho v podstatě jen skládáte aplikaci z Vašich komponent. S tím také souvisí fakt, že máte pod správou i to, jak se dané komponenty generují a jak například pracují v rámci DOMu.
U serverových aplikací jako je Apache Wicket, JSF či ASP.NET máte jen malou kontrolu nad tím, jaké Vaše výsledné komponenty nakonec generují klientský kód. Navíc, pokud budete tímto způsobem tvořit inteligentnější webovou aplikaci, která má reagovat na klientské události a měnit různé komponenty, tak se dostanete do fáze, že se Vám stejně část logiky převede na klienta, ovšem často bez štábní kultury. Nakonec se v aplikaci objeví obří javascriptové skripty, kterým rozumí pouze autor.

Proč React?

Tuhle otázku jsem si pokládal vždy, když jsem zaslechl něco o tom, proč je Angular špatný a proč je React tou pravou volbou. Pojďme si to rozebrat....

V první řadě je třeba říct, že existuje několik frameworků, které se pro single page aplikace používají. Pokud vyřadíme všechny, které hrají spíše druhé housle zůstávají dva kandidáti.

1. Angular 2 (Google)
2. React (Facebook)

Angular 2

Angular 2 se už v mnohém poučil od svého předchůdce a také se dost inspiroval samotným Reactem. Nemám zkušenosti s Angularem 1, ale údajně přináší lepší způsob tvorby komponent a také možnosti, jak tyto komponenty využívat. Současně s tím ovšem stále nese jeden velký problém a tím je závislost na DOMu. Angular 2 používá tzv zones, což v podstatě říká, že když změníte model, tak zones projde celý strom a propaguje danou změnu. Tím ovšem nekončí. Pokud provede změnu, spustí iteraci znovu a zkontroluje znovu ostatní objekty, které by zase mohly reagovat na předešlou změnu. Iterace končí ve chvíli, kdy se žádná další změna nekoná.
Na první pohled se to může zdát jako dobrá volba, nicméně faktem je, že u velkých aplikací dochází k performance problémům.

Další nespornou nevýhodou je také fakt, že Angular 2 ještě stále nevyšel a nese sebou spoustu nedodělků. Jeden příklad za všechny. Dost často narazíte na to, že pokud ve své komponentě máte chybu, tak se jí těžko dozvíte z error message. Angular Vám oznámí obecnou chybu a tím skončí. V budoucnu na tom jistě zapracují, ale v současné době je to skutečně problém.

Dalším negativem je také to, že Angular vytváří Google. Google je velice známý tím, že rád a často zabíjí své produkty a nedělá mu problém přestat podporovat něco, v čem nevidí budoucnost. Stačí se podívat na Angular 1, na kterém je v současné době 0 vývojářů.

Abych nehledal pouze chyby, dá se zde nalézt i spoustu výhod. Tou největší výhodou, oproti Reactu je fakt, že s Angularem 2 dostáváte téměř kompletní stack, který řeší view, eventy, model, http calls, apod. Tedy aplikaci struktualizujete jako template => component => service => model. Tento pattern je podobný backend systémům a pro hodně lidí bude Angular 2 možná i stravitelnější.

Existuje informace, že Angular 2 plánuje integraci JSX z Reactu. O tom, co je JSX se dozvíte níže. Nyní se pojďme podívat na React.

React

Poté, co jsem si vyzkoušel Angular 2 a napsal v něm svou cílovou aplikaci, rozhodl jsem se, že tu samou přepíši Reactem a udělám si porovnání.

V první řadě je nutné říct, že učící křivka je u Reactu velice podobná jako u Angularu. Jednou z nevýhod je fakt, že React nemá tak hezkou a uživatelsky přístupnou dokumentaci jako Angular 2. Osobně jsem měl z učení Angularu 2 lepší pocit, protože jsem vždy přesně věděl, kam se podívat.

Ale pojďme popořadě. React má oproti Angularu 2 jednu ohromnou výhodu, která ho staví do role vítěze (alespoň pro mě). A to je fakt, že není závislý na DOMu. Tedy komponenty, které zde tvoříte nemají s DOMem nic společného a React používá svůj vlastní. Samozřejmě do té doby, než začnete své komponenty svazovat věcmi jako je selector z jQuery apod. Poté se samozřejmě dostáváte do závislosti na DOMu. React komponenta se k DOMu připojuje ve fázi componentDidMount(), nicméně vy spíše využíváte onen virtuální DOM.

Proč je výhodnější virtuální DOM?

Tak za prvé je to fakt, že díky tomu můžete aplikaci renderovat na serveru, protože nejste spojeni s web browserem. A také je to fakt, že v Reactu můžete s klidem psát i mobilní aplikace, kde budete využívat komponenty mobilního SDK. K tomuto účelu slouží React Native.
Další výhodou je to, že virtuální DOM Reactu je mnohonásobně výkonnější než je tomu v případě web browseru. Odpadá tedy nutnost, kterou má Angular 2 a to je zones, tedy nutnost procházet  strom komponent a provádět změny. React to dělá inteligentněji. U větších aplikací to začne být skutečně znát.

React JSX

React pro zápis view používá JSX. Jedná se o extenzi javascript syntaxe, která umožňuje zápis ala html(xml), který je pro lidský mozek čitelnější než zápis pomocí funkcí. Ano, i když to může vypadat divně, tak JSX není xml ale funkce. Vize viz: JSX in Depth.

Věřte mi, že i když na první pohled se může zdát, že se jedná o míchání logiky a view, tak tomu tak není. Důvodem je i fakt, že pro správný návrh aplikace v Reactu stejně budete co nejvíce atomizovat jednotlivé komponenty a tím pádem logiky budou obsahovat jen minimálně.

Redux

Samotný React řeší pouze tvorbu a skládání komponent. Neřeší věci jako je AJAXové volání či service vrstvu. Každa React komponenta obsahuje dva vstupy. Jednak je to props což je model, který definuje rodič a pouze on je vlastníkem, tedy props je immutable (neměnitelný) a state. State je model, který je viditelný a měnitelný pouze v dané komponentě.
Z tohoto pohledu vznikne problém ve chvíli, kdy chcete, aby jedna komponenta reagovala na jinou, která ovšem není rodičem. K tomuto účelu slouží Redux.

Co je Redux?

Zjednodušeně se dá říct, že Redux je storage engine, který udržuje stav, který je měnitelný pomocí tzv Reducers. Reducers jsou jednoduché funkce, které přijímají současný stav a akci. Návratovou hodnotou je opět stav, který se propíše do daného store storage.
Redux udržuje pattern "one way binding". Tedy vy máte pod kontrolou změnu modelu. Více viz: Redux.

Osobně doporučuji Redux využít. Samozřejmě až po tom, co člověk ovládne samotný React.

Redux není přímou součástí Reactu. Tedy Redux můžete využít i například s Angularem 2.

Závěr

Pokud jste na rozcestí a přemýšlíte o tom, kterou cestou se dát, nezapomeňte na React. Psaní komponent v Reactu je zábava a současně také Vás nenutí využívat předem definovaný stack. React za Vás neurčí jak přes http volat API, ani Vám nepředepisuje jak má vypadat model či šlužby. Dělá pouze to, že umožňuje tvořit komponenty, spojovat komponenty a reagovat na události. A věřte, že to dělá zatraceně dobře.

A perlička na závěr. Kolik znáte angular aplikací? Myslím veřejných. V případě Reactu je odpověď jednoduchá: Facebook a Instagram :)

Když programátor založí a řídí firmu

Jako malý jsem chtěl být popelářem. Ani ne tak proto, že bych měl nějaký zvláštní vztah k odpadkům, ale hrozně se mi líbilo, jak...