Ich muss sofort sagen, dass die Site schneller funktioniert, wenn Sie Bootstrap durch reines CSS und JS ersetzen. In diesem Artikel geht es darum, wie Sie schnell mit der Entwicklung schöner Webanwendungen beginnen können. Die Optimierung ist bereits ein separates Thema, das über den Rahmen dieses Artikels hinausgeht.
Zuerst müssen Sie mindestens ein wenig HTML, CSS, JavaScript, XML, DOM, OOP verstehen und in der Lage sein, im Terminal (Befehlszeile) zu arbeiten.
In diesem Artikel werde ich das für die Arbeit notwendige Minimum zusammenpressen und einen solchen Timer erstellen:

Installation
Zuerst brauchen wir einen Paketmanager. Ich habe 
npm gewählt und es ist in 
Node.js.Installieren Sie 
Node.js zunächst auf Ihrem Betriebssystem von der offiziellen Website: 
nodejs.org/en/download . Sie können die Installation herausfinden, daher werde ich den Installationsprozess nicht beschreiben. Ich stelle nur fest, dass die Installation unter Ubuntu einfach ist:
sudo apt update sudo apt install nodejs sudo apt install npm 
Über das Terminal überprüfen wir, ob Node.js und npm erfolgreich installiert wurden:
 nodejs -v npm -v 
Wenn während der Ausgabe Fehler auftreten, bedeutet dies, dass ein Fehler aufgetreten ist und Sie ihn verstehen müssen. Sie können ihn erneut installieren. Wenn vc mit Zahlen und Punkten angezeigt wird, ist alles in Ordnung.
Installieren Sie die Create-React-App, damit Sie schnell Anwendungsframeworks erstellen können:
 npm install -g create-react-app 
Als Nächstes erstellen wir das Anwendungsframework für React. Nennen wir unsere Anwendung 
new-app . Wenn Sie eine Anwendung für einen Ordner erstellen möchten, der sich vom Benutzerordner unterscheidet, gehen Sie zuerst mit dem 
Befehl cd über das Terminal zum Terminal. Geben Sie im Terminal einfach 3 Befehle ein:
 create-react-app new-app cd new-app npm start 
Wir erstellen die 
neue App- Anwendung. Wechseln Sie in den Ordner " 
Neue App ". Wir starten die Anwendung. Nach diesen Zeilen sollte der Browser mit der React-Anwendung unter der Adresse 
http: // localhost: 3000 starten

Das Terminal sollte geöffnet bleiben, ohne es wird die Anwendungsseite nicht geöffnet. Wenn Sie plötzlich geschlossen haben, spielt es keine Rolle. Es reicht aus, den 
Befehl cd zu verwenden, um zum Anwendungsordner zu wechseln und ihn mit dem Befehl 
npm start zu startenInstallieren Sie nun Bootstrap
 npm install bootstrap 
Es wird auch empfohlen, die Abhängigkeiten von jquery und popper.js darauf zu installieren, diese werden jedoch nur für den Bootstrap JS-Teil benötigt. Ich habe es ohne sie versucht - der CSS-Teil von Bootstrap funktioniert einwandfrei, daher sind die folgenden Zeilen im Terminal optional:
 npm install jquery popper.js 
Als Nächstes müssen Sie Änderungen an den Anwendungsdateien vornehmen. Wechseln Sie dazu in den Ordner new-app, in dem sich die Anwendung befindet, und fügen Sie die Zeile zur Datei 
src / index.js hinzu. Dies sollte die erste sein:
 import 'bootstrap/dist/css/bootstrap.min.css'; 
Wenn Sie jQuery, popper.js oder den Bootstrap JS-Teil (modale Fenster, Animationen usw.) verwenden, müssen Sie unter der ersten Zeile drei weitere Zeilen hinzufügen:
 import $ from 'jquery'; import Popper from 'popper.js'; import 'bootstrap/dist/js/bootstrap.bundle.min'; 
Jetzt muss das Projekt noch ausgeführt werden:
 npm start 
Und wieder öffnet sich der Browser unter 
http: // localhost: 3000, wobei die Anwendung bereits mit Bootstrap geadelt wurde:

Zum Debuggen von React können Sie auch die Erweiterung " 
React Developer Tools " für den Browser installieren. Aktuelle Links zur Erweiterung für 
Chrome und 
Firefox sowie zu anderen Anwendungsfällen finden Sie im offiziellen Repository 
github.com/facebook/react-devtoolsDie Installation und Ersteinrichtung ist nun abgeschlossen.
JSX, Komponenten und Eigenschaften
Mal sehen, welche 
Create-React-App für uns generiert wurde - die Quelldateien befinden sich im Verzeichnis src. Schauen wir uns zunächst die Datei 
index.js an - es gibt mehrere Importzeilen. Aus den Zeilen geht hervor, was sie tun, daher werde ich keinen Kommentar abgeben.
Die wichtigste Zeile in dieser Datei:
 ReactDOM.render(<App />, document.getElementById('root')); 
Es zeichnet die Anwendungsseite. In der HTML-Quelldatei befindet sich ein 
<div> -Element mit id = root. Dieses 
<div> zeigt die 
App- Komponente an, die von der 
Renderfunktion der 
ReactDOM- Klasse gezeichnet wird. In diesem Fall wird die Komponente in einer XML-ähnlichen Form gezeichnet, die als JSX bezeichnet wird (worüber später).
Fahren wir nun mit der Datei 
App.js fort , in der sich die Implementierung der App-Klasse befindet, die von der 
React.Component- Klasse erbt.
 class App extends React.Component {     <b>render()</b>,     JSX: <div className="App"> <header className="App-header"> <img src={logo} className="App-logo" alt="logo" /> <p> Edit <code>src/App.js</code> and save to reload. </p> <a className="App-link" href="https://reactjs.org" target="_blank" rel="noopener noreferrer" > Learn React </a> </header> </div> 
JSX ist HTML sehr ähnlich, aber es gibt JS-Code-Einfügungen in geschweiften Klammern {}. Und es muss ein Stammelement geben, in diesem Fall <div>.
Zum besseren Verständnis löschen wir den gesamten Code der 
render () -Methode und schreiben die einfachste Komponente:
 class App extends React.Component { render() { return <h1>, {this.props.name}!</h1>; } } 
Kehren wir nun zur Datei index.js zurück und korrigieren sie.
 ReactDOM.render(<App name="" />, document.getElementById('root')); 
Nach dem Speichern der Dateien wird die Seite im Browser aktualisiert. Und jetzt werden wir verstehen.
Konzeptionell ähneln Komponenten JavaScript-Funktionen. Sie nehmen beliebige Daten (sogenannte Requisiten) und geben React-Elemente zurück, die beschreiben, was auf dem Bildschirm angezeigt werden soll. Mit Komponenten können Sie die Benutzeroberfläche in unabhängige, wiederverwendbare Teile unterteilen und mit jedem einzeln arbeiten.
Wenn React erkennt, dass ein Element eine benutzerdefinierte Komponente ist, werden alle JSX-Attribute als einzelnes Objekt an diese Komponente übergeben. Ein solches Objekt nennt man Requisiten.
Im Beispiel wird der Parameter 
name als Attribut des 
<App> -Tags mit dem Wert " 
World " an die Komponente übergeben. In der 
render () -Methode der 
App- Klasse geben geschweifte Klammern 
{} als Ergebnis einer Funktion in JSX, die eigentlich eine HTML-Vorlage ist, 
dies an - die aktuelle Klasse, 
Requisiten - das Benutzerobjekt, den 
Namen - den Namen des Objektparameters.
Konstruktor, Lebenszyklus und Zustandsänderung
Zusätzlich zu den in 
Requisiten gespeicherten Parametern können Sie den Status des Objekts im 
Status speichern.
Machen wir einen Timer. Für den Timer werden keine Parameter benötigt. Entfernen Sie daher die Parameter in 
index.js :
 ReactDOM.render(<App/>, document.getElementById('root')); 
Und jetzt ersetzen 
wir in der Datei 
App.js den gesamten Text zwischen 
Import und 
Export :
 const INTERVAL = 100; class App extends Component { constructor(props) { super(props); this.state = {value: 0}; } increment(){ this.setState({value: this.state.value + 1}); } componentDidMount() { this.timerID = setInterval(() => this.increment(), 1000/INTERVAL); } componentWillUnmount() { clearInterval(this.timerID); } render() { const value = this.state.value return ( <div> <p>:</p> <p> <span>{Math.floor(value/INTERVAL/60/60)} : </span> <span>{Math.floor(value/INTERVAL/60) % 60} : </span> <span>{Math.floor(value/INTERVAL) % 60} . </span> <span>{value % INTERVAL}</span> </p> </div> ); } } 
Nach dem Einfügen und Speichern dieses Codes wird ein Timer auf der Seite angezeigt und automatisch gestartet.
Lassen Sie uns diesen Code analysieren. Vor dem Unterricht wurde eine Konstante angekündigt, mit der Sie die Bildwiederholfrequenz des Timers einstellen können.
Als nächstes gibt es innerhalb der Klasse einen obligatorischen Konstruktor der Klasse, an den Requisiten übergeben werden. Als nächstes ist die Standardverarbeitung des Konstruktors der übergeordneten Klasse 
super (Requisiten) und das Bestimmen des 
Wertzustands durch 
dieses das aktuelle Objekt. Dies ist der einzige Ort, an dem Sie den Status direkt festlegen können. An anderen Stellen ist nur das Lesen verfügbar oder das Festlegen des Status mit der speziellen 
setState () -Methode, die in der nächsten 
increment () -Methode verwendet wird, um den 
Wertstatus um eins zu erhöhen.
In Anwendungen mit vielen Komponenten ist es sehr wichtig, Ressourcen freizugeben, die von Komponenten belegt werden, wenn diese zerstört werden. Wir müssen jedes Mal einen Timer einstellen, wenn das DOM zum ersten Mal gezeichnet wird. In React wird dies als "mount / install" bezeichnet. Wir müssen diesen Timer auch jedes Mal löschen, wenn das von der Komponente erstellte DOM gelöscht wird. In React wird dies als "Absteigen / Absteigen" bezeichnet.
Hierzu werden die Methoden 
componentDidMount () und 
componentWillUnmount () verwendet . In der Dokumentation werden diese Methoden als " 
Lifecycle Hooks " bezeichnet. Der Einfachheit halber werden wir sie Lebenszyklusmethoden nennen. Die 
componentDidMount () -Methode wird ausgelöst, nachdem die Komponente im DOM gerendert wurde. Dies ist ein guter Ort, um einen Timer einzustellen. Wir werden den Timer in der 
componentWillUnmount () -Methode des Lebenszyklus löschen.
Beachten Sie, wie wir in 
componentDidMount () die Timer-ID mithilfe der Pfeilfunktion direkt darin speichern. Während this.props unabhängig von React installiert wird und 
this.state eine bestimmte Bedeutung hat, können Sie der Klasse manuell zusätzliche Felder hinzufügen, wenn Sie etwas speichern müssen, das nicht für die visuelle Ausgabe verwendet wird. Wenn Sie in 
render () nichts verwenden, sollte es sich nicht im Status 
state befinden .
Ferner ist für die Dauer des 
render () - Laufs der Wertezustand im lokalen konstanten Wert festgelegt. Und dann erhalten wir mit der mathematischen Funktion 
floor () , die die Zahl abrundet, dividiert ( 
/ ) und den Rest der Division ( 
% ) erhält, die Teile des Timers, die dann in derselben Zeile nach dem Wort Timer angezeigt werden. Sie können die Ergebnisse unserer Arbeit sehen.
Aussehen mit Bootstrap
Es ist nicht praktisch, dass der Timer sofort funktioniert, wenn die Seite aktualisiert wird. Ich möchte, dass es startet und stoppt, wenn Sie auf die entsprechenden Schaltflächen klicken. Und ich möchte, dass es in der Mitte und groß ist.
Beginnen wir mit dem Design. 
Fügen Sie dazu der Datei 
App.css die folgenden Zeilen 
hinzu :
 .container-fluid { display: flex; flex-direction: column; } 
Dank des adaptiven Gummibehälter 
-Flüssigkeitsbehälters in Bootstrap können Sie ein vollständig flexibles Layout für eine Seite oder einen Block erstellen. Dieser Behälter ist 100% breit. Erstellen wir einen 
Flex- Container mit der Richtung, in der die Elemente vertikal ausgerichtet werden - so dass er den gesamten Raum einnimmt und in der Mitte ausgerichtet werden kann.
Lassen Sie uns nun die 
render () -Methode in 
App.js finalisieren , um Bootstrap-Stile anzuwenden und einige Schaltflächen hinzuzufügen. Ersetzen Sie dazu den von der Methode zurückgegebenen Wert durch den folgenden:
 <div class="container-fluid align-items-center"> <h1 class="display-1"></h1> <h1 class="display-1"> <span><kbd>{Math.floor(value/INTERVAL/60/60)}</kbd> : </span> <span><kbd>{Math.floor(value/INTERVAL/60) % 60}</kbd> : </span> <span><kbd>{Math.floor(value/INTERVAL) % 60}</kbd> . </span> <span><kbd>{value % INTERVAL < 10 ? '0' : ''}{value % INTERVAL}</kbd></span> </h1> <div> <button class="display-4"></button> <button class="display-4"></button> </div> </div> 
In der ersten Zeile wurden dem Stamm 
<div> 2 Bootstrap-Klassen hinzugefügt: 
container-fluid (über die ich oben geschrieben habe) und 
align-items-center - wodurch nur die Containerelemente in der Mitte ausgerichtet werden.
Als nächstes zwei 
<div> mit der Klasse 
display-1 - diese Klasse dient nur zum 
Anzeigen von großem Text.
Als nächstes wurde den Zahlen ein neues 
<kbd> -Tag hinzugefügt, mit dem normalerweise die Tasten hervorgehoben werden, die gedrückt werden müssen. In diesem Fall eignet es sich hervorragend zum Kontrastieren der angezeigten Zahlen.
Der bedingte Ausdruck wird in der letzten Ziffer hinzugefügt und zeigt einen Teil einer Sekunde. Dadurch können einstellige Ziffern (<10) am Anfang 0 ausgegeben werden und nicht für zweistellige Zahlen. Dies ist notwendig, damit die Zahlen nicht jede Sekunde zucken. Verwenden Sie dazu den ternären JavaScript-Operator: 
Bedingung? wahr: falschDann habe 
ich in einem separaten 
<div> 2 Schaltflächen mit der 
Display-4- Klasse platziert - diese Klasse wurde als die am besten geeignete ausgewählt, damit die Schaltflächen der Größe des Timers entsprechen. Ich habe ein Zeichen zwischen die Schaltflächen eingefügt 
  - Untrennbarer Raum, damit die Schaltflächen nicht zusammengeführt werden.
Sie können starten, aber die Schaltflächen funktionieren noch nicht. Lassen Sie uns Tasten zum Arbeiten beibringen.
Ereignisbehandlung
Fügen Sie den Aufruf zunächst den entsprechenden Funktionen im Schaltflächenausgabecode hinzu:
 <button class="display-4" onClick={this.stopTimer}></button> <button class="display-4" onClick={this.resetTimer}></button> 
Beachten Sie, dass in React der 
onClick- Ereignishandler und nicht 
onclick wie in JavaScript und die aufgerufene Funktion in geschweiften Klammern ohne Klammern angegeben sind und das Objekt angeben, von dem aus die Methode aufgerufen wird, in diesem Fall 
dies .
Nun definieren wir die angegebenen Methoden 
stopTimer () und 
resetTimer () :
 stopTimer(){ clearInterval(this.timerID); } resetTimer(){ this.setState({value: 0}); } 
Dies reicht jedoch immer noch nicht aus. Wenn Sie es so belassen, wird beim Drücken der Taste ein Fehler angezeigt. Dies ist beim Aufrufen der Funktion 
undefiniert . Dies liegt daran, dass in JavaScript Klassenmethoden nicht standardmäßig gebunden sind. Wenn Sie danach auf eine Methode ohne () 
verweisen , z. B. 
onClick = {this.resetTimer} , müssen Sie diese Methode 
normalerweise binden.
Binden Sie die Methoden im Klassenkonstruktor, indem Sie 2 Zeilen hinzufügen:
 this.stopTimer = this.stopTimer.bind(this); this.resetTimer = this.resetTimer.bind(this); 
Großartig, es hat funktioniert! Es kann jedoch nur einmal die Stopptaste verwendet werden, und danach funktionieren die Tasten nicht mehr. Dies ist logisch, da wir durch Aufrufen von 
stopTimer () den regulären Funktionsaufruf durch Aufrufen von 
clearInterval () deaktiviert haben .
In den Kommentaren wurde die Verwendung von Pfeilfunktionen vorgeschlagen. Versucht es funktioniert. Sie können dem Konstruktor also keine 2 Zeilen hinzufügen, sondern die Funktionen selbst durch die folgenden Pfeilfunktionen ersetzen:
 stopTimer = () => { this.timerID = setInterval(() => this.increment(), 1000/INTERVAL); } resetTimer = () => { this.setState({value: 0}); } 
Um dies zu lösen, wird die Schaltfläche "Stopp" auch als "Ausführen" verwendet.
Fügen Sie dem Konstruktor zunächst den 
gestoppten booleschen Status hinzu, um zu verstehen, in welchem Modus die Schaltfläche funktioniert:
 this.state = {value: 0, stopped: false}; 
Ersetzen Sie nun den Inhalt der 
stopTimer () -Methode vollständig:
 this.setState({stopped: !this.state.stopped}); if(this.state.stopped){ clearInterval(this.timerID); } else { this.timerID = setInterval(() => this.increment(), 1000/INTERVAL); }; 
Ändern Sie zu Beginn der Methode den Status 
stop über 
setState () in den entgegengesetzten 
Zustand .
Wenn der Timer gestoppt werden soll (d. H. 
Gestoppt = wahr ), deaktivieren wir den regulären Funktionsaufruf über 
clearInterval () , und wenn der Timer gestartet werden soll (d. H. 
Gestoppt = falsch ), starten wir den regulären Funktionsaufruf auf die gleiche Weise wie 
componentDidMount () .
Sie müssen auch die Methode 
increment () so korrigieren, dass sie stoppt, wenn 
gestoppt wird = true :
 increment(){ if(!this.state.stopped) (this.setState({value: this.state.value + 1})); } 
Und schließlich ändern wir den Namen der Schaltfläche abhängig vom Status "Angehalten" und fügen anstelle von "Anhalten" Folgendes ein:
 {this.state.stopped?'':''} 
Jetzt haben wir einen schönen, praktischen Timer.
Anstelle eines Abschlusses oder einer Kirsche auf einem Kuchen
Abschließend möchte ich den Standardtitel und das Fenstersymbol in unser Symbol ändern.
Sie können den Titel ändern, indem Sie 
document.title in der 
componentDidMount () -Methode festlegen. Wir werden jedoch fortfahren und die Anzeigedauer des Seitentitels auf Sekunden genau festlegen. Dazu fügen wir der speziellen 
componentDidUpdate () -Methode die 
document.title- Einstellung hinzu:
 componentDidUpdate(){ const value = this.state.value; if (this.state.stopped) document.title = ""; else document.title = ": "+Math.floor(value/INTERVAL/60/60)+":" +Math.floor(value/INTERVAL/60) % 60+":"+Math.floor(value/INTERVAL) % 60; } 
Jetzt wiederholt sich der Timer im Seitentitel bis zu Sekunden, und wenn der Timer angehalten wird, wird nur das Wort Timer angezeigt.
Das Symbol ist einfach. Es reicht aus, ein Bild im Format 
jpg , 
bmp , 
gif , 
png vorzubereiten, es in den 
öffentlichen Ordner (und nicht in den 
src , in dem wir hauptsächlich gearbeitet haben) zu legen, beispielsweise 
favicon.png zu benennen und die Zeile in der Datei 
public \ index.html zu ändern:
 <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico"> 
pro Zeile:
 <link rel="shortcut icon" type="image/png" href="/favicon.png"/> 
Für heute war das alles, was ich sagen wollte. Im nächsten Artikel werde ich mehr über Bootstrap sprechen, das in diesem Artikel nur geringfügig berührt wurde. Neben Bootstrap gibt es noch wichtige Themen: Listen, Tabellen, Formulare und Denken im React-Stil.
Schließlich das Repository in BitBucket, das den gesamten Code für diesen Artikel enthält