Java týden Java týden
Aprílový black friday tě nenechá v klidu! Až 80 % prémiového obsahu zdarma. Více informací
Pouze tento týden slevy až 80 % na programování v Javě

Lekce 4 - Dokončení React kalkulačky

JavaScript React Dokončení React kalkulačky

ONEbit hosting Unicorn College Tento obsah je dostupný zdarma v rámci projektu IT lidem. Vydávání, hosting a aktualizace umožňují jeho sponzoři.

V minulé lekci, Komponenty React kalkulačky, jsme začali programovat Rect komponenty naší jednoduché kalkulačky. Tu jsme zvolili jako dostatečně jednoduchý projekt k vyzkoušení základů React. V dnešním React tutoriálu budemem pokračovat a naši první skutečnou aplikaci zcela dokončíme! :)

src/calculator/O­perationSelec­t.js

Ostatní naše komponenty budou vypadat hodně podobně jako ty, co jsme si vytvořili minule. Jako další na řadu si vezmeme komponentu pro výběr operace:

import React, { Component } from 'react';

export default class OperationSelect extends Component {
    constructor(props) {
        super(props);
        const value = this.props.value;
        this.state = { value: value ? value : '' };
        this.handleChange = this.handleChange.bind(this);
    }

    handleChange(event) {
        const value = event.target.value;
        this.setState({ value });
        this.props.onChange(value ? value : null);
    }

    render() {
        const { label, name, operations } = this.props;

        const options = Object.keys(operations).map((value, index) => {
            return <option key={index} value={value}>{operations[value]}</option>
        });

        return (
            <label htmlFor={name}>
                {label}
                <select id={name} required
                    value={this.state.value}
                    onChange={this.handleChange}>
                    <option value="">--Vyberte operaci--</option>
                    {options}
                </select>
            </label>
        );
    }
}

Vidíte opět práci s vlastnostmi, stavem a jeho změnami. Co možná stojí za zmínku, je způsob vykreslení možností (option) pro seznam operací. Zde pro jejich sestavení použijeme JS map(), přičemž pro jednoduché vložení do JSX jim musíme dát jejich unikátní klíče (key=...).

src/calculator/O­peration.js

Už se nám to pěkně rýsuje, ale ještě před úpravou komponenty formuláře kalkulačky si definujeme její aktuálně podporované operace. Je to hlavně z toho důvodu, že by naše kalkulačka měla být do budoucna snadno rozšiřitelná. A jelikož nejsme barbaři, definujeme si je hezky do samostatného souboru:

const Operation = Object.freeze({
    ADD: 'add',
    SUBTRACT: 'subtract',
    MULTIPLY: 'multiply',
    DIVIDE: 'divide'
});

export default Operation;

Pokud umíte JS, tak k tomu snad není co dodat.

src/calculator/Cal­culatorForm.js

A zlatým hřebem bude samotná komponenta pro formulář kalkulačky, kde veškerou předchozí funkcionalitu propojíme a také zde definujeme naše výpočty:

import React, { Component } from 'react';
import NumberInput from './NumberInput';
import Operation from './Operation';
import OperationSelect from './OperationSelect';

export default class CalculatorForm extends Component {
    constructor(props) {
        super(props);
        this.operations = {
            [Operation.ADD]: 'Sčítání',
            [Operation.SUBTRACT]: 'Odčítání',
            [Operation.MULTIPLY]: 'Násobení',
            [Operation.DIVIDE]: 'Dělení'
        };
        this.state = { x: 0, y: 0, operation: null, result: null };

        const handleChange = (name, value) => this.setState({ [name]: value });
        this.handleChangeX = handleChange.bind(this, 'x');
        this.handleChangeY = handleChange.bind(this, 'y');
        this.handleChangeOperation = handleChange.bind(this, 'operation');
        this.handleSubmit = this.handleSubmit.bind(this);
    }

    calculate() {
        const { x, y, operation } = this.state;
        switch (operation) {
            case Operation.ADD: return x + y;
            case Operation.SUBTRACT: return x - y;
            case Operation.MULTIPLY: return x * y;
            case Operation.DIVIDE: return x / y;
            default: return null; // Sem by to nikdy nemělo dojít.
        }
    }

    handleSubmit(event) {
        event.preventDefault();
        const result = this.calculate();
        this.setState({ result });
        this.props.onResultChange(result);
    }

    render() {
        return (
            <form className="CalculatorForm" onSubmit={this.handleSubmit}>
                <NumberInput name="x" label="První číslo:"
                    value={this.state.x}
                    onChange={this.handleChangeX} />
                <NumberInput name="y" label="Druhé číslo:"
                    value={this.state.y}
                    onChange={this.handleChangeY} />
                <OperationSelect name="operation" label="Operace:"
                    operations={this.operations}
                    value={this.state.operation}
                    onChange={this.handleChangeOperation} />
                <input type="submit" value="Spočítej" />
            </form>
        );
    }
}

Na první pohled to vypadá možná trochu komplikovaně, ale ve skutečnosti zde není nic, co bychom už neznali :) Je zde definice stavu, operací, výpočtu výsledku a jeho propagace při odeslání formuláře pomocí události onSubmit.

Princip je takový, že díky propagaci stavů komponent vždy víme o hodnotách v nich uložených. Pokud pak uživatel formulář odešle, zamezíme výchozí akci pomocí event.preventDefault() a následně z hodnot spočítáme výsledek, který dále propagujeme.

src/App.js

Nakonec ještě zajistíme předání výsledku do komponenty pro jeho výpis v rámci naší aplikace:

import React, { Component } from 'react';
import CalculatorForm from './calculator/CalculatorForm';
import Result from './calculator/Result';
import './App.css';

export default class App extends Component {
    constructor(props) {
        super(props);
        this.state = { result: null };
        this.propagateResult = result => this.setState({ result });
    }

    render() {
        const title = 'React kalkulačka';

        return (
            <div className="App">
                <h1>{title}</h1>
                <CalculatorForm onResultChange={this.propagateResult} />
                <Result value={this.state.result} />
            </div>
        );
    }
}

Tady už by také nemělo být nic překvapivého :)

Styly

Tímto je práce na komponentách hotova, ale my si ještě na závěr doplňme CSS, aby naše aplikace alespoň trochu vypadala.

src/App.css

Zde pro jednoduchost dáme styl ke komponentě naší aplikace, protože jinde není v podstatě co stylizovat:

.App {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
}

label {
    display: block;
    clear: both;
    margin: 10px 0;
}

label > input, label > select {
    margin-left: 5px;
}

label > input {
    float: right;
}

input[type="submit"] {
    display: block;
    margin: 0 auto;
}

.Result {
    font-size: 1.5em;
    font-weight: bold;
    margin: 10px 0;
}

Jak vidíte v rámci CSS hezky využijeme názvy tříd našich komponent.

A tím je naše práce na celém projektu dokončena. Pokud se teď podíváte na spuštěnou aplikaci, měli byste vidět funkční kalkulačku a můžete na ní vyzkoušet všechny chytáky, které vás napadnou :)

Pokud vám není cokoli jasné, stáhněte si projekt z přílohy a projeďte si ho. Kódu v aplikaci tolik nemáme, po chvíli byste se v principu měli zorientovat.

V příloze nejsou nainstalované moduly, kvůli jejich velikost. Je tedy potřeba před spuštěním aplikace použít příkaz npm install.

To je pro tuto lekci opravdu vše. Příště, v lekci , začneme úplně novou pořádnou aplikaci za použití React knihovny. A co to bude, to se nechte překvapit! ;)


 

Stáhnout

Staženo 5x (147.87 kB)
Aplikace je včetně zdrojových kódů v jazyce JavaScript

 

 

Článek pro vás napsal Jindřich Máca
Avatar
Jak se ti líbí článek?
Ještě nikdo nehodnotil, buď první!
Autor se věnuje převážně webovým technologiím, ale má velkou zálibu ve všem vědeckém, nejen ze světa IT. :-)
Miniatura
Předchozí článek
Komponenty React kalkulačky
Miniatura
Všechny články v sekci
React
Aktivity (1)

 

 

Komentáře

Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zatím nikdo nevložil komentář - buď první!