Jeśli odrobiłeś poprzednią lekcję to teraz zrobimy prosty kalkulator i utrwalimy wiedzę związaną ze stanami komponentów. Analogiczny kalkulator, ale w języku JavaScript opisałem w tutorialu: „KALKULATOR W JS”. Porównaj oba rozwiązania 🙂
Gotowy kod:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>React.js</title> <script src="https://unpkg.com/react/umd/react.development.js"></script> <script src="https://unpkg.com/react-dom/umd/react-dom.development.js"></script> <script src="https://unpkg.com/babel-standalone/babel.js"></script> <style type="text/css"> #calculator { background: #eaeaea; margin: 0 auto; padding: 35px 25px 35px 25px; width: 200px; text-align: center; } #calculator button { padding: 10px; width: 40px; } #calculator input[type="text"] { padding: 10px; width: 147px; margin-bottom: 5px; } </style> </head> <body> <div id="calculator"></div> <script type="text/babel"> class Calculator extends React.Component { constructor(props) { super(props); this.state = { a: '', b: '', result: 'result = ' }; this.handleChangeA = this.handleChangeA.bind(this); this.handleChangeB = this.handleChangeB.bind(this); this.handleCalculate = this.handleCalculate.bind(this); } render() { return ( <div> <form> <input type="text" onChange={this.handleChangeA} value={this.state.a} placeholder="a"/> <input type="text" onChange={this.handleChangeB} value={this.state.b} placeholder="b"/> <input type="text" value={this.state.result} placeholder="result" disabled="disabled" /> <button type="button" onClick={this.handleCalculate}>+</button> <button type="button" onClick={this.handleCalculate}>-</button> <button type="button" onClick={this.handleCalculate}>x</button> <button type="button" onClick={this.handleCalculate}>/</button> </form> </div> ); } handleChangeA(e) { this.setState({ a: e.target.value }); } handleChangeB(e) { this.setState({ b: e.target.value }); } handleCalculate(e) { e.preventDefault(); switch(e.target.innerText) { case '+': var result = parseFloat(this.state.a) + parseFloat(this.state.b); break; case '-': var result = parseFloat(this.state.a) - parseFloat(this.state.b); break; case 'x': var result = parseFloat(this.state.a) * parseFloat(this.state.b); break; case '/': var result = parseFloat(this.state.a) / parseFloat(this.state.b); break; } this.setState({ result: 'result = ' + result }); } } ReactDOM.render(<Calculator />, document.getElementById('calculator')); </script> </body> </html> |
Wyjaśnienie:
- W konstruktorze ustawiamy początkowe stany (state) dla pól tekstowych (input type=”text”): a, b i result. Wiążemy (bind) funkcje (handleChangeA, handleChangeB, handleCalculate) z instancją komponentu Calculator.
1 2 3 4 5 6 7 8 9 10 11 |
constructor(props) { super(props); this.state = { a: '', b: '', result: 'result = ' }; this.handleChangeA = this.handleChangeA.bind(this); this.handleChangeB = this.handleChangeB.bind(this); this.handleCalculate = this.handleCalculate.bind(this); } |
- Funkcja handleChangeA – reaguje na zdarzenie onChange pola tekstowego z przypisanym stanem a; e.target.value – zwraca wartość pola input, na którym wywołano zdarzenie (e = event):
1 |
<input type="text" onChange={this.handleChangeA} value={this.state.a} placeholder="a"/> |
1 2 3 |
handleChangeA(e) { this.setState({ a: e.target.value }); } |
- Funkcja handleChangeB – reaguje na zdarzenie onChange pola tekstowego z przypisanym stanem b:
1 |
<input type="text" onChange={this.handleChangeB} value={this.state.b} placeholder="b"/> |
1 2 3 |
handleChangeB(e) { this.setState({ b: e.target.value }); } |
- Funkcja handleCalculate – oblicza i przekazuje wynik operacji matematycznych do this.state.result. Funkcja ta reaguje na zdarzenie onClick poszczególnych przycisków:
1 2 3 4 |
<button type="button" onClick={this.handleCalculate}>+</button> <button type="button" onClick={this.handleCalculate}>-</button> <button type="button" onClick={this.handleCalculate}>x</button> <button type="button" onClick={this.handleCalculate}>/</button> |
Kod funkcji:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
handleCalculate(e) { e.preventDefault(); switch(e.target.innerText) { case '+': var result = parseFloat(this.state.a) + parseFloat(this.state.b); break; case '-': var result = parseFloat(this.state.a) - parseFloat(this.state.b); break; case 'x': var result = parseFloat(this.state.a) * parseFloat(this.state.b); break; case '/': var result = parseFloat(this.state.a) / parseFloat(this.state.b); break; } this.setState({ result: 'result = ' + result }); } |
- e.preventDefault() – wyłącza akcję na obiekcie, tzn. że po kliknięciu przycisku nie nastąpi przeładowanie strony. Instrukcja switch jako argument pobiera treść klikniętego przycisku (e.target.innerText), wykonuje odpowiednią operację matematyczną i aktualizuje stan – this.setState:
1 |
this.setState({ result: 'result = ' + result }); |
Wynik (this.state.result) jest wyświetlany w polu input:
1 |
<input type="text" value={this.state.result} placeholder="result" disabled="disabled" /> |