NILS HARTMANN React MODERNE WEB-ANWENDUNGEN MIT · •Objekt mit Key-Value-Paaren •Zugriff über...

43
BED-CON BERLIN | SEPTEMBER 2017 | @NILSHARTMANN React NILS HARTMANN Slides: http://bit.ly/bedcon-react MODERNE WEB-ANWENDUNGEN MIT

Transcript of NILS HARTMANN React MODERNE WEB-ANWENDUNGEN MIT · •Objekt mit Key-Value-Paaren •Zugriff über...

Page 1: NILS HARTMANN React MODERNE WEB-ANWENDUNGEN MIT · •Objekt mit Key-Value-Paaren •Zugriff über this.state/ this.setState() •Nur in Komponenten-Klassenverfügbar •this.setState()

BED-CON BERLIN | SEPTEMBER 2017 | @NILSHARTMANN

ReactNILS HARTMANN

Slides:http://bit.ly/bedcon-react

MODERNE WEB-ANWENDUNGEN MIT

Page 2: NILS HARTMANN React MODERNE WEB-ANWENDUNGEN MIT · •Objekt mit Key-Value-Paaren •Zugriff über this.state/ this.setState() •Nur in Komponenten-Klassenverfügbar •this.setState()

@NILSHARTMANN

NILS HARTMANNProgrammierer aus Hamburg

JavaJavaScript, TypeScript

Trainings und Workshops

https://reactbuch.de

Page 3: NILS HARTMANN React MODERNE WEB-ANWENDUNGEN MIT · •Objekt mit Key-Value-Paaren •Zugriff über this.state/ this.setState() •Nur in Komponenten-Klassenverfügbar •this.setState()

HINTERGRUND: SINGLE PAGE APPLICATIONS

Klassische Webanwendung• JSP, Thymeleaf, JSF• jQuery

Single Page Application• REST API• React, Angular, Vue

Page 4: NILS HARTMANN React MODERNE WEB-ANWENDUNGEN MIT · •Objekt mit Key-Value-Paaren •Zugriff über this.state/ this.setState() •Nur in Komponenten-Klassenverfügbar •this.setState()

BEISPIEL ANWENDUNG

https://github.com/nilshartmann/react-example-app/tree/typescript

Page 5: NILS HARTMANN React MODERNE WEB-ANWENDUNGEN MIT · •Objekt mit Key-Value-Paaren •Zugriff über this.state/ this.setState() •Nur in Komponenten-Klassenverfügbar •this.setState()

KOMPONENTEN

<PasswordView><PasswordForm><input /><CheckLabelList><CheckLabel /><CheckLabel />

</CheckLabelList><Label /><Button />

</PasswordForm></PasswordView>

Page 6: NILS HARTMANN React MODERNE WEB-ANWENDUNGEN MIT · •Objekt mit Key-Value-Paaren •Zugriff über this.state/ this.setState() •Nur in Komponenten-Klassenverfügbar •this.setState()

Grafik Inspiriert von: https://pbs.twimg.com/media/DCXJ_tjXoAAoBbu.jpg

SEPARATION OF CONCERNS

RETHINKING BEST PRACTICES

But

ton

Eing

abef

eld

Labe

l

View(HTML, Template)

Logik, Model(JS)

Gestaltung(CSS)

Klassische Aufteilung Aufteilung in Komponenten

Page 7: NILS HARTMANN React MODERNE WEB-ANWENDUNGEN MIT · •Objekt mit Key-Value-Paaren •Zugriff über this.state/ this.setState() •Nur in Komponenten-Klassenverfügbar •this.setState()

KOMPONENTENB

utto

n

Eing

abef

eld

Labe

l

View(HTML, Template)

Logik, Model(JS)

Gestaltung(CSS)

React-Komponenten• bestehen aus Logik und UI• kein CSS

• keine Templatesprache• werden deklarativ beschrieben• werden immer komplett

gerendert

• können auf dem Server gerendert werden („universal webapps“)

Page 8: NILS HARTMANN React MODERNE WEB-ANWENDUNGEN MIT · •Objekt mit Key-Value-Paaren •Zugriff über this.state/ this.setState() •Nur in Komponenten-Klassenverfügbar •this.setState()

REACT SCHRITT FÜR SCHRITT

Page 9: NILS HARTMANN React MODERNE WEB-ANWENDUNGEN MIT · •Objekt mit Key-Value-Paaren •Zugriff über this.state/ this.setState() •Nur in Komponenten-Klassenverfügbar •this.setState()

DIE JSX SPRACHERWEITERUNG

Anstatt einer Template Sprache: HTML in JavaScript integrieren• Erlaubt Schreiben von HTML-artigen Ausdrücken im JavaScript-Code• Wird zu regulärem JavaScript Code compiliert (z.B. Babel, TypeScript)• Optional

const name = 'Lemmy';const greeting = <h1>Hello, {name}</h1>;

var name = 'Lemmy';var greeting = React.createElement('h1', null, 'Hello, ', name);

JSX

Übersetztes JavaScript

Page 10: NILS HARTMANN React MODERNE WEB-ANWENDUNGEN MIT · •Objekt mit Key-Value-Paaren •Zugriff über this.state/ this.setState() •Nur in Komponenten-Klassenverfügbar •this.setState()

EINE REACT KOMPONENTE: ALS FUNKTION

function CheckLabel() {return <divclassName="CheckLabel-unchecked">At least 8 characters long.

</div>;}

JSXKomponentenfunktion

Komponente CheckLabel

Page 11: NILS HARTMANN React MODERNE WEB-ANWENDUNGEN MIT · •Objekt mit Key-Value-Paaren •Zugriff über this.state/ this.setState() •Nur in Komponenten-Klassenverfügbar •this.setState()

KOMPONENTE EINBINDEN

<html><head>. . .</head><body><div id=“mount“></div>

</body><script src=“dist/dist.js“></script>

</html>

index.html

Page 12: NILS HARTMANN React MODERNE WEB-ANWENDUNGEN MIT · •Objekt mit Key-Value-Paaren •Zugriff über this.state/ this.setState() •Nur in Komponenten-Klassenverfügbar •this.setState()

KOMPONENTE EINBINDEN

import React from 'react';import ReactDOM from 'react-dom';

import CheckLabel from './CheckLabel';

ReactDOM.render(<CheckLabel />, document.getElementById('mount')

);

app.js

Page 13: NILS HARTMANN React MODERNE WEB-ANWENDUNGEN MIT · •Objekt mit Key-Value-Paaren •Zugriff über this.state/ this.setState() •Nur in Komponenten-Klassenverfügbar •this.setState()

KOMPONENTEN: PROPERTIES

function CheckLabel(props) {return <div className={props.checked?'CheckLabel-checked':'CheckLabel-unchecked'}>{props.label}

</div>;}

{checked: false,label: ‘At least 8 characters long.’ }

Page 14: NILS HARTMANN React MODERNE WEB-ANWENDUNGEN MIT · •Objekt mit Key-Value-Paaren •Zugriff über this.state/ this.setState() •Nur in Komponenten-Klassenverfügbar •this.setState()

KOMPONENTEN VERWENDEN

function CheckLabelList() {return <div> <CheckLabel checked={false}

label='At least 8 characters long' />

<CheckLabel checked={true} label='Contains uppercase letters.' />

</div>;}

CheckLabelList CheckLabel

• Komponenten sind zusammensetzbar

Page 15: NILS HARTMANN React MODERNE WEB-ANWENDUNGEN MIT · •Objekt mit Key-Value-Paaren •Zugriff über this.state/ this.setState() •Nur in Komponenten-Klassenverfügbar •this.setState()

BEISPIEL: KOMPONENTENLISTEN

function CheckLabelList(props) {return <div>

// . . .

</div>;}

checks: [{ checked: false, label: ‘At least 8 characters long.’ },{ checked: true, label: ‘Contains uppercase letters’ }

]

Page 16: NILS HARTMANN React MODERNE WEB-ANWENDUNGEN MIT · •Objekt mit Key-Value-Paaren •Zugriff über this.state/ this.setState() •Nur in Komponenten-Klassenverfügbar •this.setState()

BEISPIEL: KOMPONENTENLISTEN

function CheckLabelList(props) {return <div>{props.checks.map(c => <CheckLabel

label={c.label}checked={c.checked}key={c.label} />)

}</div>;

}

checks: [{ checked: false, label: ‘At least 8 characters long.’ },{ checked: true, label: ‘Contains uppercase letters’ }

]

Page 17: NILS HARTMANN React MODERNE WEB-ANWENDUNGEN MIT · •Objekt mit Key-Value-Paaren •Zugriff über this.state/ this.setState() •Nur in Komponenten-Klassenverfügbar •this.setState()

KOMPONENTEN KLASSEN

class CheckLabelList extends React.Component {constructor(props) { super(props);

}

componentDidMount() { . . . }componentWillReceiveProps() { . . . }shouldComponentUpdate() { . . . }

render() {return <div>{this.props.checks.map(c => <CheckLabel . . ./>)}

</div>;}

}

ECMAScript 2015 Klasse

Properties über Konstruktor(optional)

Lifecycle Methoden(optional)

Render-Methode (pflicht)

Properties über propsObjekt

Page 18: NILS HARTMANN React MODERNE WEB-ANWENDUNGEN MIT · •Objekt mit Key-Value-Paaren •Zugriff über this.state/ this.setState() •Nur in Komponenten-Klassenverfügbar •this.setState()

ZUSTAND VON KOMPONENTEN

Zustand („state“): Komponenten-intern• Beispiel: Inhalt von Eingabefeld, Antwort vom Server• Objekt mit Key-Value-Paaren• Zugriff über this.state / this.setState()• Nur in Komponenten-Klassen verfügbar• this.setState() triggert erneutes Rendern

• auch alle Unterkomponenten• Kein 2-Wege-Databinding

Zum Vergleich: Properties• Von außen übergeben• Unveränderlich• Zugriff über this.props (Key-Value-Paare)

Page 19: NILS HARTMANN React MODERNE WEB-ANWENDUNGEN MIT · •Objekt mit Key-Value-Paaren •Zugriff über this.state/ this.setState() •Nur in Komponenten-Klassenverfügbar •this.setState()

BEISPIEL: EINGABEFELD

PasswordForm

Interner Zustand!

input

Page 20: NILS HARTMANN React MODERNE WEB-ANWENDUNGEN MIT · •Objekt mit Key-Value-Paaren •Zugriff über this.state/ this.setState() •Nur in Komponenten-Klassenverfügbar •this.setState()

BEISPIEL: EINGABEFELD

inputZustand!

class PasswordForm extends React.Component {render() {return <div><inputvalue={this.state.password}

/>. . .

</div>;}

}

1. Input mit Wert aus State befüllen

Page 21: NILS HARTMANN React MODERNE WEB-ANWENDUNGEN MIT · •Objekt mit Key-Value-Paaren •Zugriff über this.state/ this.setState() •Nur in Komponenten-Klassenverfügbar •this.setState()

BEISPIEL: EINGABEFELD

inputZustand!

class PasswordForm extends React.Component {render() {return <div><inputvalue={this.state.password}onChange={e=>this.onPasswordChange(e.target.value)}

/>. . .

</div>;}

onPasswordChange(newPassword) {

}}

1. Input mit Wert aus State befüllen2a. Event Handler registrieren

2b. Event Handler

Page 22: NILS HARTMANN React MODERNE WEB-ANWENDUNGEN MIT · •Objekt mit Key-Value-Paaren •Zugriff über this.state/ this.setState() •Nur in Komponenten-Klassenverfügbar •this.setState()

BEISPIEL: EINGABEFELD

inputZustand!

class PasswordForm extends React.Component {render() {return <div><inputvalue={this.state.password}onChange={e=>this.onPasswordChange(e.target.value)}

/>. . .

</div>;}

onPasswordChange(newPassword) {this.setState({password: newPassword});

} }

1. Input mit Wert aus State befüllen2a. Event Handler registrieren

2b. Event Handler

3. Zustand neu setzen

Page 23: NILS HARTMANN React MODERNE WEB-ANWENDUNGEN MIT · •Objekt mit Key-Value-Paaren •Zugriff über this.state/ this.setState() •Nur in Komponenten-Klassenverfügbar •this.setState()

ZUSTAND: EINGABEFELD

inputZustand!

class PasswordForm extends React.Component {render() {return <div><inputvalue={this.state.password}onChange={e=>this.onPasswordChange(e.target.value)}

/>. . .

</div>;}

onPasswordChange(newPassword) {this.setState({password: newPassword});

} }

Neu rendern

Event

1. Input mit Wert aus State befüllen2a. Event Handler registrieren

2b. Event Handler

3. Zustand neu setzen

Page 24: NILS HARTMANN React MODERNE WEB-ANWENDUNGEN MIT · •Objekt mit Key-Value-Paaren •Zugriff über this.state/ this.setState() •Nur in Komponenten-Klassenverfügbar •this.setState()

REACT: UNI DIRECTIONAL DATAFLOW

class PasswordForm extends React.Component {onPasswordChange(newPassword) { this.setState({password: newPassword); }. . .render() {const password = this.state.password;const checks = this.checkPassword(password);const failedChecks = . . .;const isValidPassword = failedChecks === 0;

return <div><input type='password'

value={password}onChange={event => this.onPasswordChange(event.target.value)} />

<CheckLabelList checks={checks}/>

{failedChecks > 0 ?<div className='Label'>{failedChecks} checks failed</div>:<div className='Label Label-success'>All checks passed!</div>

}

<Button label='Set Password' enabled={isValidPassword} /></div>;

}}

Event

Zustand Rendern

RESPOND TO EVENTS & RENDER UI

Page 25: NILS HARTMANN React MODERNE WEB-ANWENDUNGEN MIT · •Objekt mit Key-Value-Paaren •Zugriff über this.state/ this.setState() •Nur in Komponenten-Klassenverfügbar •this.setState()

VIRTUAL DOM

DOMVirtual DOMKomponente

renderReact

State & Props

Page 26: NILS HARTMANN React MODERNE WEB-ANWENDUNGEN MIT · •Objekt mit Key-Value-Paaren •Zugriff über this.state/ this.setState() •Nur in Komponenten-Klassenverfügbar •this.setState()

ZUGRIFF AUF NATIVE DOM ELEMENTE

DOMVirtual DOMKomponente

renderReact

State & Props

class PasswordForm extends React.Component {render() {return <div><inputref={ domNode => this.inputNode = domNode }. . .

/></div>;

}}

Page 27: NILS HARTMANN React MODERNE WEB-ANWENDUNGEN MIT · •Objekt mit Key-Value-Paaren •Zugriff über this.state/ this.setState() •Nur in Komponenten-Klassenverfügbar •this.setState()

KOMMUNIKATION

Kommunikation zwischen Komponenten: Callbacks

Page 28: NILS HARTMANN React MODERNE WEB-ANWENDUNGEN MIT · •Objekt mit Key-Value-Paaren •Zugriff über this.state/ this.setState() •Nur in Komponenten-Klassenverfügbar •this.setState()

TypeScriptby Example

PASSWORD FORM

PasswordForm

Page 29: NILS HARTMANN React MODERNE WEB-ANWENDUNGEN MIT · •Objekt mit Key-Value-Paaren •Zugriff über this.state/ this.setState() •Nur in Komponenten-Klassenverfügbar •this.setState()

HTTPS://NILSHARTMANN.NET | @NILSHARTMANN

Vielen Dank!

Fragen?http://bit.ly/bedcon-react

Page 30: NILS HARTMANN React MODERNE WEB-ANWENDUNGEN MIT · •Objekt mit Key-Value-Paaren •Zugriff über this.state/ this.setState() •Nur in Komponenten-Klassenverfügbar •this.setState()

Anhang

Page 31: NILS HARTMANN React MODERNE WEB-ANWENDUNGEN MIT · •Objekt mit Key-Value-Paaren •Zugriff über this.state/ this.setState() •Nur in Komponenten-Klassenverfügbar •this.setState()

"JavaScript that scales"

TypeScriptHTTP://WWW.TYPESCRIPTLANG.ORG/

Page 32: NILS HARTMANN React MODERNE WEB-ANWENDUNGEN MIT · •Objekt mit Key-Value-Paaren •Zugriff über this.state/ this.setState() •Nur in Komponenten-Klassenverfügbar •this.setState()

HINTERGRUND: TYPESCRIPT

TypeScript: Obermenge von JavaScript mit Typ-System• Gültiger JavaScript-Code auch gültiger TypeScript-Code• Compiler übersetzt TypeScript in JavaScript-Code• Unterstützt auch JSX

• Sehr guter IDE Support • z.B. IDEA, Eclipse, VS Code

Page 33: NILS HARTMANN React MODERNE WEB-ANWENDUNGEN MIT · •Objekt mit Key-Value-Paaren •Zugriff über this.state/ this.setState() •Nur in Komponenten-Klassenverfügbar •this.setState()

TYPESCRIPT - SYNTAX

Typen verwendenVariablenlet foo: string; // eingebaute Typen z.B: string, number, booleanfoo = "yo";foo = 10; // Fehler: Type 'number' is not assignable to type 'string'

Page 34: NILS HARTMANN React MODERNE WEB-ANWENDUNGEN MIT · •Objekt mit Key-Value-Paaren •Zugriff über this.state/ this.setState() •Nur in Komponenten-Klassenverfügbar •this.setState()

TYPESCRIPT - SYNTAX

Typen verwendenVariablenlet foo: string; // eingebaute Typen z.B: string, number, boolean

Funktionenfunction sayIt(what: string) {

return `Saying: ${what}`; }sayIt('Klaus'); // OKsayIt(10); // Fehler (10 is not a string)

Page 35: NILS HARTMANN React MODERNE WEB-ANWENDUNGEN MIT · •Objekt mit Key-Value-Paaren •Zugriff über this.state/ this.setState() •Nur in Komponenten-Klassenverfügbar •this.setState()

TYPESCRIPT - SYNTAX

Typen verwendenVariablenlet foo: string; // eingebaute Typen z.B: string, number, boolean

Funktionenfunction sayIt(what: string) {

return `Saying: ${what}`; }

Angabe von Typen ist optional, Typen werden dann abgeleitet:let result = 7; abgeleiteter Typ: numberresult = sayIt('Lars') // Fehler (abgeleiteter Typ von sayIt: string)

Page 36: NILS HARTMANN React MODERNE WEB-ANWENDUNGEN MIT · •Objekt mit Key-Value-Paaren •Zugriff über this.state/ this.setState() •Nur in Komponenten-Klassenverfügbar •this.setState()

TYPESCRIPT - SYNTAX

Eigene Typen definiereninterface Person { // Alternativ: typefirstName: string, lastName: string|null, // nullable Typ ("ein String oder null")age?: number // optionaler Typ

}

Page 37: NILS HARTMANN React MODERNE WEB-ANWENDUNGEN MIT · •Objekt mit Key-Value-Paaren •Zugriff über this.state/ this.setState() •Nur in Komponenten-Klassenverfügbar •this.setState()

TYPESCRIPT - SYNTAX

Eigene Typen definieren und verwendeninterface Person { // Alternativ: typefirstName: string, lastName: string|null, // nullable Typ ("ein String oder null")age?: number // optionaler Typ

}

function sayHello(p: Person) {console.log(`Hello, ${p.lastName}`);p.lastName.toUpperCase(); // Fehler: Object is possibly null

}

sayHello({firstName: 'Klaus', lastName: null}); // OKsayHello({firstName: 'Klaus', lastName: 777}); // Fehler: lastName kein StringsayHello({firstName: 'Klaus', lastName: 'Mueller', age: 32}); // OK

Page 38: NILS HARTMANN React MODERNE WEB-ANWENDUNGEN MIT · •Objekt mit Key-Value-Paaren •Zugriff über this.state/ this.setState() •Nur in Komponenten-Klassenverfügbar •this.setState()

TYPESCRIPT - SYNTAX

Genericstype Person = { name: string };type Movie = { title: string };

let persons:Array<Person> = [];let movies:Array<Movie> = [];

persons.push({name: 'Klaus'}); // OKmovies.push({title: 'Batman'}); // OKpersons.push({title: 'Casablanca'}) // error ('title' not in Person)

Page 39: NILS HARTMANN React MODERNE WEB-ANWENDUNGEN MIT · •Objekt mit Key-Value-Paaren •Zugriff über this.state/ this.setState() •Nur in Komponenten-Klassenverfügbar •this.setState()

für React-Anwendungen

TypeScript

Page 40: NILS HARTMANN React MODERNE WEB-ANWENDUNGEN MIT · •Objekt mit Key-Value-Paaren •Zugriff über this.state/ this.setState() •Nur in Komponenten-Klassenverfügbar •this.setState()

TYPESCRIPT UND REACT: PROPERTIES

function CheckLabel(props: CheckLabelProps) {. . .

}

interface CheckLabelProps {label: string,checked?: boolean

};

Typ definieren

Überprüfung zur Compile-Zeit(auch direkt in der IDE)

Properties als Typen in TypeScript

Page 41: NILS HARTMANN React MODERNE WEB-ANWENDUNGEN MIT · •Objekt mit Key-Value-Paaren •Zugriff über this.state/ this.setState() •Nur in Komponenten-Klassenverfügbar •this.setState()

TYPESCRIPT UND REACT: PROPERTIES & STATE

interface PasswordFormProps { restrictions: Restriction[];onPasswordSet: (password: string) => void;

};

interface PasswordFormState {password?: string;

};

1. Typen definieren

Komponenten-Klassen als Generics• Typ für Properties und State

Page 42: NILS HARTMANN React MODERNE WEB-ANWENDUNGEN MIT · •Objekt mit Key-Value-Paaren •Zugriff über this.state/ this.setState() •Nur in Komponenten-Klassenverfügbar •this.setState()

TYPESCRIPT UND REACT: PROPERTIES & STATE

interface PasswordFormProps { restrictions: Restriction[];onPasswordSet: (password: string) => void;

};

interface PasswordFormState = {password?: string;

};

class PasswordForm extendsComponent<PasswordFormProps, PasswordFormState> {. . .

}

1. Typen definieren

2. Typen als Parameter angeben

Komponenten-Klassen als Generics• Typ für Properties und State

Page 43: NILS HARTMANN React MODERNE WEB-ANWENDUNGEN MIT · •Objekt mit Key-Value-Paaren •Zugriff über this.state/ this.setState() •Nur in Komponenten-Klassenverfügbar •this.setState()

TYPESCRIPT UND REACT: PROPERTIES & STATE

// Properties sind read-onlythis.props.restrictions = null;

// Nur bekannte Properties dürfen verwendet werdenconst x = this.props.not_here;

// State muss vollständig initialisiert werdenthis.state = {}; // password fehlt

// this.state darf nur im Konstruktor verwendet werdenthis.state.password = null; // außerhalb des Cstr

// Elemente im State müssen korrekten Typ habenthis.setState({password: 7}); // 7 is not a string

// Unbekannte Elemente dürfen nicht in den State gesetzt werdenthis.setState({notHere: 'invalid'});

Potentielle Fehler

Typische Fehler, die durch TypeScript aufgedeckt werden