Java Training Block 10 – Tag 5 React

Ich nehme derzeit an einer Akademie zum Java Fullstack Software Engineer teil. In den kommenden Wochen möchte ich hier meine Mitschrift, so gut es geht, aufzeichnen und mitteilen. Hier ist das, was ich vom fünften Tag (mit etwas Verspätung) in Block 10 gelernt und behalten habe:

Flux, Redux, AJAX

In React wollen wir Daten von einem Objekt zum anderen übertragen. Die Objekte in einer HTML-Seite sind hierarchisch angeordnet. Ein Objekt kann Daten an den Reducer senden. Der leitet sie (reduziert) weiter an einen Store.
Objekte, die sich an dem Store registriert haben, erhalten ein Update für ihre Daten, sobald sich dort etwas ändert.

Siehe auch: https://react-redux.js.org/

Input und Output müssen sich am Reducer registrieren. Nachdem der Client seine Nachrichten gesendet hat, fängt eine Funktionalität an zu arbeiten. Diese Logik beeinflusst den Store. Der Store erkennt die Änderungen und informiert die Mitglieder der Liste. Daraufhin ändern sich die States der Empfänger.

Beispiel: \Block10-React\day05\my-redux-app:

Die Konstante counterreducer ist ein eine Methode, wo im ersten Teil die Daten übergeben werden und im zweiten Teil die Logik steht. Hier als unvollständiges Beispiel, wo State auch ein Objekt (Radius,…) sein könnte:

In Zeile 14 wird der Store mit dem Reducer kombiniert. Store weiß dann, was er zu verwalten hat. Im Store wird das State gehalten:

Hier noch der Inhalt von index.js und reducer.js:

Store erbt von Object und hat einige Default-Funktionen intus. Z.B. Store.subscribe,…

Registrierung des Render-Objektes:

Zeile 50-53 erzeugt eine Haupt-Komponente, speichert sie in einer Konstanten "render" und meldet sich als Subscriber am Store (Reduzer) an.

Wir erzeugen eine Referenz-Variable und können sie dann registrieren.

Im klassischen Weg wird das Rendern direkt ausgeführt (Kommentar Zeile 57). Jetzt (Zeile 51) wird das Ausführen einer Konstante übergeben (Hier jetzt "builder").

In Zeile 52 wird diese Konstante (welches eine Funktion ist) ausgeführt und in 53 wird diese Konstante an den Store übergeben.

Die Funktionen increment und decrement führen im Store die entsprechenden Aktionen aus:


Wir installieren das Redux DevTool im Chrome-Browser

https://chrome.google.com/webstore/detail/redux-devtools/lmhkpmbekcpmknklioeibfkpmmfibljd?hl=en

Wir können nun im Log (Strg-Shift-I) rechts oben auf den Redux-Button klicken und sehen einige Informationen mehr:

Weitere Beispiele:

Kap1601-flux-redux

AJAX /XHR / Promise / windows.fetch

Wir kopieren unser Template in ein neues ueb-ajax Projekt. Wir benennen das Projekt im package.json in "ueb-ajax" um (Zeile 2):

Hier der funktionierrende Code von app.jsx:

import logo from './logo.svg';
import './App.css';
import React from 'react';

class App extends React.Component {
constructor(props) {
// Private PropertieInformation
// Data / Model
super(props);

// Private StateInformation
// Data / Model
this.state = {
  "url"    : 'https://swapi.dev/api/planets/1/',
  "status" : '',
  "data" : ''
};

// Databinding an die  private States binden
// ReadOnly auf die States für die angegebene Methode aufheben
this.handlerButtonFetch = this.handlerButtonFetch.bind(this);
this.handlerButtonClear = this.handlerButtonClear.bind(this);

}
// Service
getDataXHR() {
console.log("Call: getDataXHR");
// 1. Local XHR erzeugen
let xhr = new XMLHttpRequest(); // ab ECMA-5.1
// 2. Init / Config des XHR-Objektes
xhr.open("GET", this.state.url, true);
// 3. Call-Back-Funktion einbinden als Lambda-Ausdrücke
xhr.onloadstart = () => {
console.log("xhr.onloadstart");
this.setState({ "status": "Load" });
};
xhr.onloadend = () => {
console.log("xhr.onloadend");
console.log("Data: " + xhr.responseText);
this.setState({ "status": "Loadend" });
this.setState({ data: xhr.responseText });
};
xhr.onprogress = () => {
console.log("xhr.onprogress");
this.setState({ "status": "OnProgress" });
;
};
// 4. Senden
xhr.send(); // bei GET xhr.send(); bei POST xhr.send(data); -> data in den RequestBody
}
// Control
handlerButtonClear(event){
this.setState({status : "Clean"});
this.setState({data : "Leer"});
}

// Control
handlerButtonFetch(event){
  this.setState({status : "Fetch"});
  this.getDataXHR();
}

render() {
return (
<div className="App">
<h1>AJAX-SWAPI</h1>
<hr/>
<div className="App">
<h1>Starwars-API</h1>
<hr/>
<button onClick={this.handlerButtonFetch}>Fetch Data</button>
<button onClick={this.handlerButtonClear}>Clear</button>
<hr/>
<div >
<div>URL: {this.state.url} </div>
<div>Status: {this.state.status} </div>
<div>Data: {this.state.data} </div>
</div>
</div>
</div>

);

}
}
export default App;

Fetch ist ein alternativer Ansatz zu xhr.

Ein Promise ist das Versprechen, dass es irgendwann erfüllt wird. Es gibt drei Zustände: Erfüllt, Abgelehnt, ausstehend.

Das Fetch basiert auf einem Promise. Fetch macht eine Pipeline über AJAX-Antworten.

Wenn es gut geht, wird das Ergebnis in einen JSON-Datenstrom umgewandelt, danach kommt der nächste Befehl. Nach dem Komma werden die Fehlerfälle bearbeitet:

Fetch geht auch mit POST:

Xhr funktioniert immer noch, aber fetch ist moderner und kürzer.

Beispiel Katzen-Api:

Hier das funktionierende Katzen-Api-Beispiel-Script:

App.jsx:

import React from 'react';

class App extends React.Component {
constructor(props) {
super(props);
this.state = {
breed: 'abys',
error: null,
isLoaded: false,
breedList: [],
data: []
};
this.handleGET = this.handleGET.bind(this);
this.handleChangeBreed = this.handleChangeBreed.bind(this);
}

componentDidMount() {
    this.handleBreeds()
}

handleChangeBreed(event) {
    this.setState({ breed: event.target.value });
}
handleBreeds() {
    fetch("https://api.thecatapi.com/v1/breeds")
        .then(res => res.json())
        .then(
            (result) => {
                this.setState({
                    isLoaded: true,
                    breedList: result
                })
            },
            (error) => {
                this.setState({
                    isLoaded: true,
                    error
                });
            }
        )
}

handleGET() {
    console.log("Call handleGET")
    fetch("http://api.thecatapi.com/v1/images/search?breed_ids=" + this.state.breed)
        .then(res => res.json())
        .then(
            (result) => {
                this.setState({
                    data: result
                })
            },
            (error) => {
                this.setState({
                    error
                });
            }
        )
}

render() {
    const { error, isLoaded, data } = this.state;
    if (this.state.isLoaded) {
        return (
            &lt;div>
                &lt;h1>Katzen Rassen:&lt;/h1>&lt;br />
                &lt;button onClick={this.handleGET} className="btn btn-primary">Katze!&lt;/button>
                &lt;select value={this.state.breed} onChange={this.handleChangeBreed}>
                    {this.state.breedList.map(b => (&lt;option value={b.id}>{b.name}&lt;/option>))}
                &lt;/select>
                &lt;hr />
                {data.map(d => (&lt;div>
                    &lt;ul>
                        {d.breeds.map(breed => (&lt;div>
                            &lt;li>Zucht: {breed.name}&lt;/li>
                            &lt;li>Alternative Bezeichnungen: {breed.alt_names}&lt;/li>
                            &lt;li>Beschreibung:
                                &lt;p>{breed.description}&lt;/p>
                            &lt;/li>
                            &lt;li>Lebenserwartung: {breed.life_span}&lt;/li>
                            &lt;li>Herkunft: {breed.origin}&lt;/li>
                            &lt;li>Wikipedia Link: &lt;a href={breed.wikipedia_url} >{breed.wikipedia_url}&lt;/a>&lt;/li>
                            &lt;li>Bild:&lt;br />
                                &lt;img alt={d.name} height={d.height * 0.3} width={d.width * 0.3} src={d.url}>&lt;/img>
                            &lt;/li>
                        &lt;/div>))}
                    &lt;/ul>
                &lt;/div>
                ))}
            &lt;/div>);
    }
    else {
        return (
            &lt;div>
                &lt;h1>Lade...&lt;/h1>
            &lt;/div>);
    }
}

}

export default App;

Übung KUG-Buch

  • Katzenrassen ersetzen ducrh Book-list (Fetch URL) (Zeile 25)
  • Constructore-Daten durch KUG-Daten erstzen (Array mit Bucheigenschaften)
  • Unten im Renderbereich die Daten aus den Büchern auflisten

Wir wollen, basierend auf dem Katzen-API Script-Beispiel, unsere KUG-Buch Datenbank an ein React-Script anschließen. (Nach einer Woche mit morgens 2 h ausprobieren hat es dann auch endlich geklappt):

Hier das funktionierende Script von App.jsx:

import React from 'react';
import ReactDOM from 'react-dom';
class App extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            book: '',
            error: null,
            isLoaded: false,
            bookList: [],
            data: []
        };
        this.handleGET = this.handleGET.bind(this);
        this.handleChangeBook = this.handleChangeBook.bind(this);
    }
    componentDidMount() {  //Zugriff auf die Methode geben
        this.handleBooks()
    }
    handleChangeBook(event) { //Zugriff auf die Methode geben
        this.setState({ book: event.target.value });
    }
    handleBooks() {  //Daten holen
        fetch("http://localhost:8099/kugcontroller/buecherliste")
            .then(res => res.json())
            .then(
                (result) => {
                    this.setState({
                        isLoaded: true,
                        bookList: result //Das komplette zurückgelieferte JSON-Objekt wird in bookList gespeichert
                    })
                },
                (error) => {
                    this.setState({
                        isLoaded: true,
                        error
                    });
                }
            )
    }
    handleGET() { //liest den Inhalt aus dem Auswahl-Feld aus und schreibt die gewünschten Daten in den State
        var booklist = (this.state.bookList);  //Wir schreiben den erhaltenen JSON-String in eine lokale Variable
        // um besser an die Elemente zu kommen  
        console.log("booklist = " + JSON.stringify(booklist));
        console.log(this.state.bookList[0]); // Das hier geht
        console.log("BookList[0] = " + this.state.bookList[0]); //Das hier nicht
        console.log("BookList[0] = " + JSON.stringify(this.state.bookList[0])); //Das geht wieder
        var myinput = document.getElementById('mySelect');  // Inhalt aus mySelect-Button in myInput schreiben
        console.log("value = " + ReactDOM.findDOMNode(myinput).value);  //Das ist die ISBN-Nummer aus dem im Feld "mySelect" ausgewählten Eintrag
        var isbn = ReactDOM.findDOMNode(myinput).value;
    booklist.forEach(element => {  // Nun gehen wir durch alle Bücher in der Liste durch ...
        console.log("Element = " + JSON.stringify(element));
        if (element.isbn === isbn) {   //... und suchen das Element (Buch) mit der gemerkten ISBN-Nummer 
            console.log("Element.isbn = " + element.isbn);
            console.log("Elemen.titel = " + element.titel);
            this.setState({ selectedTitel: element.titel }) // Wir merken uns im State den Titel, autor, jahr und preis:
            this.setState({ selectedAutor: element.autor })
            this.setState({ selectedJahr: element.jahr })
            this.setState({ selectedPreis: element.preis })
        }
    });
    this.setState({ selectedISBN: isbn }); //Wir merken uns im State die ausgesuchte ISBN-Nummer
}
// So sieht das Katzenbeispiel aus:
/*
handleGET() {
    console.log("Call handleGET")
    fetch("http://api.thecatapi.com/v1/images/search?breed_ids=" + this.state.breed)
        .then(res => res.json())
        .then(
            (result) => {
                this.setState({
                    data: result
                })
            },
            (error) => {
                this.setState({
                    error
                });
            }
        )
}
*/
render() {
    const { error, isLoaded, data } = this.state; // der komplette State wird in data gespeichert
    if (this.state.isLoaded) {
        return (
            &lt;div>
                &lt;h1>Kug-Buch:&lt;/h1>&lt;br />
                &lt;button onClick={this.handleGET} className="btn btn-primary">Buch!&lt;/button>
                &lt;select id="mySelect" value={this.state.book} onChange={this.handleChangeBook}>
                    {this.state.bookList.map(b => (&lt;option value={b.isbn}>{b.titel}&lt;/option>))}
                &lt;/select>
                &lt;hr />
                {data.map(d => (&lt;div>
                    &lt;ul>
                        {d.bookList.map(book => (&lt;div>
                            &lt;li>Titel: {book.titel}&lt;/li>
                        &lt;/div>))}
                    &lt;/ul>
                &lt;/div>
                ))}
                {console.log("SelectedISBN = " + this.state.selectedISBN)}
                &lt;div>
                    &lt;hr />
                    &lt;h3>Buchinhalt:&lt;/h3>

BuchISBN = {this.state.selectedISBN} <br />
Buchtitel = {this.state.selectedTitel} <br />
BuchAutor = {this.state.selectedAutor} <br />
BuchJahr = {this.state.selectedJahr} <br />
BuchPreis = {this.state.selectedPreis} <br />
</div>
<hr />
ISBN-Nummer vom ersten Buch:
{this.state.bookList[0].isbn} <br />
<h3>Bücherliste:</h3>
{
this.state.bookList.map(book => (<div>
Buchname: {book.titel}
</div>))
}

            &lt;/div>);
    }
    else {
        return (
            &lt;div>
                &lt;h1>Lade...&lt;/h1>
            &lt;/div>);
    }
}

}
export default App;


Zusammenfassung React

------------------------------------------------------------------------------------------
Block 10 - React
------------------------------------------------------------------------------------------

Bücher:

  • Fullstack React: The Complete Guide to ReactJS and Friends ISBN-13: 978-0991344628; 64,30 €
  • Learning React: Modern Patterns for Developing React Apps ISBN-13: 978-1492051725; 46,96 €
  • React: Das umfassende Handbuch für moderne Frontend-Entwicklung.ISBN-13: 978-3836268776; 39,90 €
  • React: Grundlagen, fortgeschrittene Techniken und Praxistipps – mit TypeScript und Redux ISBN-13: 978-3864905520; 34,30 €

Links:

Tutorials:

Material

Umgebung:

node -v Version
npm -v Version
npm ls -g Globes Installationsverzeichnis für die NodeJS - Module : C:\Users\joachim\AppData\Roaming\npm

Proxy-Settintgs:

User-Home-Verz:\nodejs-14.17.npmrc

npm config set proxy http://username:password@host:port
npm config set https-proxy http://username:password@host:port

Telekom-Proxy:

npm config set proxy http://...:8080/
npm config set https-proxy http://...:8080/

Überblick Arbeiten mit ReactJS-Projekten

Entwicklungsumgebung einrichten
npm install -g create-react-app
npm ls -g

Anlegen eines ReactJS-Projekts:

Installation react, react-dom, und react-scripts mit cra-template...:
npx create-react-app my-app01

Installing react, react-dom, and react-scripts with cra-template...

npm start                       Starts the development server.
npm run build                 Bundles the app into static files for production.
npm test                        Starts the test runner.
npm run eject                 Removes this tool and copies build dependencies, configuration files  and scripts into the app directory. If you do this, you can’t go back!

cd my-app01

Übersetzen und Starten der Applikation

npm start

  • Übersetzen *.ts -> *.js
  • Zusammenpackern webpack 5.68.0 compiled successfully in 8063 ms
  • Starten eines NodeJS-Server http://localhost:3000
 > my-app01@0.1.0 start
 > react-scripts start
  ....
 Starting the development server...
 Compiled successfully!

 You can now view my-app01 in the browser.

 Local:            http://localhost:3000
  On Your Network:  http://10.0.1.238:3000

Browser http://localhost:3000/

Projektstruktur:

tree /F
C:\...\day01\my-app
│   .gitignore
│   package-lock.json
│   package.json                                        // -> pom.xml
│   README.md
│   
├───node_modules                                  // Maven
│           
├───public                                                // Static Web
│       favicon.ico
│       index.html                                        // Single-Page -> DOM
│       logo192.png
│       logo512.png
│       manifest.json
│       robots.txt
│       
└───src                                                     // Dynamic Web
        App.css                                              // App Componenten StyleSheet (View)
        App.js                                                // App Componenten Logik  (Control /Model)
        App.test.js                                         // App Componenten Test
        index.css
        index.js                                              // Verknüpfung  Static Web mit Dynamic Web
        logo.svg
        reportWebVitals.js
        setupTests.js

Single-Page: ReactJS - Applikation

public -> index.html <=> src -> index.js


Static Dynamic
<div id="root"></div> ReactDOM.render("HTML <App/>",document.getElementById('root')

                                           src -> App.js   (Funktionale Componente)
                                           -------------------------------------------------------
                                           function App() {
                                               return (
                                                   .......... "HTML" .............
                                               );
                                           }
                                           export default App;

Module

  • Global (C:\Users\joachim\AppData\Roaming\npm)
    npm install -g ...................
    npm install -g create-react-app
    npm ls -g

      C:\Users\joachim\AppData\Roaming\npm
      ├── @angular/cli@12.2.10
      ├── @popperjs/core@2.9.2
      ├── babel@6.23.0
      ├── bootstrap@4.6.0
      ├── create-react-app@5.0.0
      ├── eslint@7.26.0
      ├── jshint@2.12.0
      ├── jslint@0.12.1
      ├── karma-cli@2.0.0
      └── typescript@4.5.5
    
  • Local (Projekt-Verz./node_modules)
    npx create-react-app my-app01
    npm install ...................
    npm ls

    Zusätzliche Module lokal installieren
    npm install react-router-dom (kap14xx)
    npm install react-redux (kap15xx)
    npm install react-addons-css-transition-group (kap17xx)

     my-app01@0.1.0 C:\..........\block10-react\day01\my-app01 (node_modules)
     ├── @testing-library/jest-dom@5.16.2
     ├── @testing-library/react@12.1.2
     ├── @testing-library/user-event@13.5.0
     ├── react-dom@17.0.2                                 (Shadow-Tree)
     ├── react-redux@7.2.6
     ├── react-router-dom@6.2.1
     ├── react-scripts@5.0.0
     ├── react@17.0.2                                          (CORE-Funktionalität)
     └── web-vitals@2.1.4

REACT sucht vom Projekt ausgehend in der Hierachie nach Open (-> C:) einen node_modules-Ordener und benutzt den ersten den er findet um zu starten
Ab react@17.0..0

VOR REACT 17.0.0 muste man SymLinks einrichten
Symbolistic-Links: (aus Projekt-Verzeichniss)


  • Linux / Mac / Unix
    ln -s ../node_modules ./node_modules
    Quelle Ziel

  • Windows
    mklink /J node_modules "../node_modules"
    mklink /J node_modules "../day01/node_modules"
    mklink /J node_modules "../../node_modules"
    Ziel Quelle


React: Funktionale-Component vs. Class-Component>

Functional Components (function NAME -> return(... React-HTML ...))
-> Stateless component
-> Small Lifecycle

Class Component (class NAME -> render(return (... React-HTML ...) ))
-> Stateful component
-> Big Lifecycle

Dateiendungen:

.ts -> *.js Funtional ES-5 function App() {
return ( "HTML");
}

.tsx -> *.jsx Klassesn ES-6 class App extends React.Component {
render() {
return ( "HTML");
}
} export default App;

jsx benötigt eine Transcription Babel d.h. erneutes übersetzen!!!!

Technologien für den Renderings-Prozess

Func-Class-Componente

//Ausgabe
render() {

return(

  • React-HTML-Objekte
    • <p className="somevalue">This is the content!!!</p>
      - <p data-myattribute="somevalue">This is the content!!!</p>

            - ExpressionLanguage (AusdrucksSprache)
              {..... Ausdruck .....}
              &lt;h1>{1 + 1}&lt;/h1> 
              &lt;h1>{i === 1 ? 'True!' : 'False'}&lt;/h1>
              &lt;h1 style = {myStyle}>Header&lt;/h1>
      

      )

}

JavaScript Expressions

{} -> Natives JavaScript

// Kommentare in den Componenten (render() -> return())

{ /*Multi line comment...*/ }
// JS-Kommentar
&lt;!-- HTML-Kommentar -->

Naming Convention

HTML tags always use lowercase tag names, while React components start with Uppercase.
Note: You should use className and htmlFor as XML attribute names instead of class and for.

class -> className
for -> htmlFor (<lable>)

Props und State

Componenten Eigenschaften / Parameter

  • Props -> Properties die von aussen an eine Componente mitgegeben werden vgl. Parameter einer Funktion
    this.props
 HTML
 ------
 &lt;App    name="Homer", age ="57"/>    

 Componente
  -------------------
 class App extends React.Component {

constructor(props) {
super(props);
console.log("Show Name-Property:" + this.props.name); // Show Name-Property; Homer
}

  • State -> Eigenschaften innerhalb einer Componente um StatusInformationen zu speichern
    this.state

    constructor() {

      // Private StateInformation
      // Data / Model
     this.state = {
         "name"    : '',
         "gebjahr" : '',
         "alter" : '',
         "show" : false,
         "myStyle" : {display:'none'}
      };
    

    }

    ...
    // this.state.name = event.target.value; // So nicht da this.state.name da KEIN Access erlaubt ist ohne Bindung
    this.setState({name : event.target.value}); // setState() -> Observable ( this.state) -> render(){}

Uebung: KehrwertRechner (Single-Page -> React)

  • Berechnung augelagert (Funktion oder Methode)

  • From: input: Zahl
    button: Berechnung Aufräumen

  • Out: Zahl , Kehrwert

  • Fehlermeldung

LifeCycle

Funct-Componenten -> HOCs (Higher Order Components)
Class-Componenten -> component...... - Methoden

Event

Refs -> Referenzen in den React-DOM-Baum (Deprecated)

clearInput() {
    this.setState({ data: '' });

    //Alternative 
    var myinput = document.getElementById('myinput');
    ReactDOM.findDOMNode(myinput).focus();

    // Reference Deprecated
    ReactDOM.findDOMNode(this.refs.myInput).focus();
}

render() {
    return (
        &lt;div>
            &lt;input id='myinput' value={this.state.data} onChange={this.updateState}
                ref="myInput">&lt;/input>
            &lt;button onClick={this.clearInput}>CLEAR&lt;/button>
            &lt;h4>{this.state.data}&lt;/h4>
        &lt;/div>
    );
}

Keys -> Key wird bei Collections von React-DOM-Baum-Elementen (Intern gebraucht)

Collection [][][][][][] -> React-DOM-Baum-Elementen (<li>, <tr>, <div>,....)


JavaScript React

{this.state.data.map((dynamicComponent, i) =>
<Content key={i} componentData={dynamicComponent} />)} // n - Content-Elemente

index.js:1 Warning: Each child in a list should have a unique "key" prop.

Routing

Aufteilung unserer Browser-Darstellung in mehrere Teilbereiche die sich wahlweise Umschalten lassen

Zusätzliche Module lokal installieren:
npm install react-router-dom (kap14xx)
npm ls
c:...\my-workspace\block10-react\node_modules
...
+-- react-router-dom@5.3.0 extraneo
+-- react-router@5.2.1 extraneous

index.js

import { Route, Link, BrowserRouter as Router, Switch } from 'react-router-dom'

const routing = (
<Router>
<div>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/users">Users</Link>
</li>
<li>
<Link to="/contact">Contact</Link>
</li>
</ul>
<hr />
<Switch>
<Route exact path="/" component={App} />
<Route path="/users" component={Users} />
<Route path="/contact" component={Contact} />
<Route component={Notfound} />
</Switch>
</div>
</Router>
)
ReactDOM.render(routing, document.getElementById('app'))

Übung Routing (ueb-kreis-routing):

3 Componenten (App, Input, Output)
1 Utility-Klasse Kreisrechner

  • App -> Menü zum Umschalten zwischen Input und Output
  • Input -> Formular zur Erfassung des Radius
  • Output -> Für die Ausgabe von Radius, Fläche, Umfang

Flux / Redux

index.js

// Create Store -------------------------------------------------------
import { createStore } from 'redux'
import counterReducer from './reducer';

//Native
const store = createStore(counterReducer)

reducer.js

const counterReducer = (state = 0, action) => { // state = 0 init des Store d.h der hält hier ein Objekt vom Type Numer (state)

switch (action.type) {
    case "INCREMENT":
        return  state + 1
    case "DECREMENT":
        return state - 1
    default:
        return state
}

}
export default counterReducer

index.js

console.log(store)

{liftedStore: {…}, dispatch: ƒ, subscribe: ƒ, getState: ƒ, replaceReducer: ƒ, …}
@@@observable: ƒ ()
dispatch: ƒ e(r)
getState: ƒ i()
liftedStore: {dispatch: ƒ, subscribe: ƒ, getState: ƒ, replaceReducer: ƒ, @@@observable: ƒ}
replaceReducer: ƒ replaceReducer(r)
subscribe: ƒ subscribe(listener)
[[Prototype]]: Object

console.log("Store-State: " + store.getState());
/ / -> 0

const render = () => ReactDOM.render(<Counter />, document.getElementById('root')) // Erzeugen meiner Haupt-Componente in einer Konstanten
render() // Haupt-Componente wird gerendert
store.subscribe(render); // Haupt-Componente meldet sich als Subscribe am Store an

// Create a Counter component by using the redux state. ---------------

function increment() {
store.dispatch({ type: "INCREMENT" });
console.log("Store-State: " + store.getState());
}

function decrement() {
store.dispatch({ type: "DECREMENT" });
console.log("Store-State: " + store.getState()) ;
}

const Counter = () => {
return (
<div>
<h1>{store.getState()}</h1>
<button onClick={increment}>Increment</button>
<button onClick={decrement}>Decrement</button>
</div>
)
}

// Subscribe method ---------------------------------------------------

const builder = () => ReactDOM.render(<Counter />, document.getElementById('root'));
builder();
store.subscribe(builder);

AJAX / XHR / Promise / windo.fetch

Fetch:

const data = { username: 'example' };

fetch('https://example.com/profile', {
method: 'POST', // or 'PUT'
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
})
.then(response => response.json())
.then(data => {
console.log('Success:', data);
})
.catch((error) => {
console.error('Error:', error);
});

Disclaimer

Alles was ich mitschrieb und verstanden habe ist ohne Gewähr. Die Bilder stammen teilweise aus dem Internet und wir haben keine Urheberansprüche darauf.

Besten Dank an unseren sehr empfehlenswerten

Trainer: Hans-Joachim Blanke blanke@4point.de

Man achte auf die Schwergewichtigkeit von node_modules 

Ich habe jetzt erst mal wieder eine Recap-Woche, aber danach geht’s weiter, so: stay tuned!

Gruß, Achim Mertens

H2
H3
H4
3 columns
2 columns
1 column
Join the conversation now
Logo
Center