React
React ist ein von Facebook entwickeltes Framework zum Darstellen von HTML-UI-Komponenten. Es gibt es auch in einem React Native-"Geschmack" zum Erstellen von nativen Android- oder iOS-Apps.
Allgemeines
Das Framework wird unter einer OpenSource-Lizenz verbreitet.
Siehe
- Vertiefung der React Props - ausführlich unter Berücksichtigung neuerer JavaScript-Sprachkonstrukte
React Native
Seihe React Native
Projektstruktur
React gibt keine Projektstruktur vor. Mit Hilfe von Create-react-app kann jedoch eine Grundstruktur erzeugt werden, die von vielen React-Projekten verwendet wird. Dadurch können sich fremde Entwickler leicht darin zurecht finden.
Siehe für eine Projektstruktur mit frontend-, backend- und shared-Quellcode auch
Alternative zu create-react-app
Einen schnelleren Build-Prozess als create-react-app aufgrund des eingesetzten esbuild-Tools verspricht Vite.
Auch Parcel ist eine Alternative zu webpack, dem Bundler-Tool von create-react-app. Siehe
- https://adrianhall.github.io/javascript/react/2020/03/29/parcel-typescript-react/ - Teil 1
- https://adrianhall.github.io/javascript/react/2020/03/31/adding-storybook-to-template/ - Teil 2: mit StoryBook
- https://adrianhall.github.io/javascript/react/2020/04/02/adding-unit-testing-to-template/ - Teil 3: Jest mit Enzyme
- https://github.com/adrianhall/parcel-typescript-template/tree/main - die fertige Schablone für ein Parcel, TypeScript, React, Jest, StoryBook - Projekt
Auslieferung von relativer Serveradresse
Siehe
React und TypeScript und Webpack
Allgemeines
Siehe
- Codeburst on webpack typescript and react
Server Side Rendering
Für Server Side Rendering (SSR) oder Static Site Generation, ggf. mit späterer Hydration durch dynamische React-Elemente, gibt es
- cra-ssr (wohl veraltet)
- react-snap - arbeitet mit einem Headless Chrome im Build-Prozess
- cra-with-ssr Anleitung zu SSR mit Hydration auf Basis von CRA
- Razzle
- umfangreichere Frameworks
Als CMS-Backend z.B. für Gatsby gibt es u.a.
- strapi
React und global state management nach dem Flux-Prinzip
React und TypeScript und Redux
- https://www.typescriptlang.org/docs/handbook/react-&-webpack.html
- https://medium.com/better-programming/react-redux-with-typescript-7ff678bc17ab
- https://dev.to/leomeloxp/taking-react-and-redux-to-the-next-level-with-typescript-1m84
- Kompendium zu React, TypeScript und Redux
- Vorschlag einer Best Practice für Typensicherheit mit Redux und React
Leichtgewichtige Alternativen
Eigene (custom) react hooks
Siehe
- Erläuterung zur Nutzung von React Hooks zur Kapselung der Logik, um eine Status-ID mit einem URL-Query-Parameter zu synchronisieren.
global hook store
Mit global-hook-store hat man eine leichtgewichtige Alternative zu Redux, die React Hooks nutzt und TypeScript-Support gleich mitbringt.
Wenn man create-react-app mit TypeScript-Vorlage verwendet, kommt es bei den Jest-Unit-Tests zu Problemen. Dann hilft es, in die package.json
Folgendes aufzunehmen:
"jest": { "transformIgnorePatterns": [ "/node_modules/(?!global-hook-store).+\\.js$" ] },
Dai Shis React Hooks Global State
Dai Shi hat https://github.com/dai-shi/react-hooks-global-state implementiert
HookState.js
Siehe https://hookstate.js.org/docs/getting-started/
Recoil
Siehe
Jotai
Siehe
Testen von React
Siehe
- Enzyme
- Jest
- https://medium.com/@fay_jai/getting-started-on-testing-with-typescript-reactjs-and-webpack-a45a72f4f603
- Proxy Development Server, um API-Zugriffe an den eigenen Server senden zu können.
Lange Listen in React
Siehe
- Lange Listen darstellen während des Ladens
- Darstellen langer Listen mit React
- React-virtualized - Modul zum Anzeigen von Daten erst dann, wenn der Benutzer dies will
Ergänzungen für React
Adresszeile
Die Standardergänzung, um mit der Adresszeile zu arbeiten, ist für React der React Router.
Aber es gibt auch andere Ergänzungen
- React-Query-Params lässt mit den URI-Parametern ähnlich umgehen wie mit State oder Props.
Komponenten
Rich Text Editor
- editor.js
- kann auch Tabellen
- kann auch in React eingebettet werden
- Der CKEditor unterstützt u.a. Tabellen.
- Ihn gibt es auch in einem React-Geschmack.
- Der AlloyEditor macht sich Mühe, ihn mit kontextsensitiven Menüs auszugestalten.
- Den TinyMCE gibt es in einer Open Source- und verschiedenen kommerziellen Varianten.
- Jodit kann auch Tabellen.
- https://github.com/jodit/jodit-react (MIT Lizenz)
- https://github.com/mkhstar/suneditor-react
- https://github.com/summernote/summernote
- https://www.npmjs.com/package/react-editor-js unterstützt auch einfache Tabellen
- React Page hat wohl keine Tabellen.
- https://github.com/zenoamaro/react-quill hat wohl keine Tabellen.
Tabellenbearbeitung
Komponenten zur Nutzung in React als Editor für die Bearbeitung von Tabellen ähnlich Excel:
- AG Grid
- TanStack
- Handsontable
- Univer - muss noch geprüft werden, ob innerhalb React einsetzbar; freie Version hat Einschränkungen
Komponentensammlung
- PrimeReact bietet sehr viele UI-Komponenten.
- Das Schwesterprojekt PrimeFlex bietet CSS-Klassen.
- IBM Carbon Desgin
- Radix benützt zumindest JSX, ist möglicherweise React-basiert
- shadcn/ui ist Radix-basiert.
- Semantic UI
- Fomantic-UI - ein Open Source Fork von Semantic UI
Icons
- https://github.com/feathericons/feather bietet einfache Icons im SVG-Format unter MIT-Lizenz
- Feather-Icon-Übersicht
- react-feather
- Ionicons mit MIT-Lizenz
- Phosphor-Icons sind ebenfalls unter der MIT-Lizenz
- Bootstrap Icons können unabhängig vom Rest von Bootstrap genutzt werden.
- IBM Carbon Icons mit Apache-Lizenz und React-Unterstützung
- Übersicht über verschiedene Icon-Sets
Diagramme
- VisX ist eine umfangreiche React-basierte Bibliothek, um Daten graphisch darstellen zu können.
- https://www.npmjs.com/package/react-minimal-pie-chart
Canvas und React
Siehe
- Zeichenkomponente, die React Hooks verwendet
- Konvajs ist eine objektorientierte Zeichenbibliothek für Canvas, die auch mit React integriert
- https://react.rocks/tag/Canvas
Beispiel für TypeScript und React
Grundlegendes
Ein Projekt sollte ein Versionskontrollsystem nutzen. Ein früherer Zustand des Projekts sollte wiederhergestellt werden können. Zu diesem Zustand gehören grundsätzlich auch die Abhängigkeiten (wie externe Programmierbibliotheken).
Die folgenden Kommandozeilen setzen die Bash unter Linux oder MacOS voraus. Vieles davon dürfte - evtl. leicht modifiziert - auch auf Windows laufen.
Installation von node
Node.js kommt zwar mit der Linux-Distribution, aber wir wollen - um möglichst alle Abhängigkeiten zu definieren - mit Hilfe von nvm eine spezifische Node-Version installieren:
Im Terminal nvm-Repo klonen:
cd ~ git clone https://github.com/creationix/nvm.git .nvm cd .nvm
Folgende Zeilen an die ~/.bashrc
anfügen:
export NVM_DIR="$HOME/.nvm" [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm [ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion
Im Terminal node-LTS herunterladen und als Standard setzen:
nvm install 'lts/*' nvm alias default 'lts/*'
Projekt initialisieren
Projektverzeichnis erstellen und für GIT initialisieren:
export PROJ_DIR=~/myprojects/myproject mkdir "$PROJ_DIR" cd "$PROJ_DIR" git init
Die Datei .gitignore
erstellen:
frontend/node_modules
React-App-Verzeichnisstruktur erstellen (mit Typescript[1]):
cd "$PROJ_DIR" npx create-react-app frontend --typescript
Projekt im Entwicklungsmodus starten
cd "$PROJ_DIR" npm start
API-Requests im Entwicklungsmodus umlenken lassen
Um die AJAX-Zugriffe des Frontends während der Entwicklungsphase auf den API-Server umzulenken, nimmt man in die frontend/package.json
etwa folgende Zeile auf:
"proxy": "http://localhost:4000"
Der Entwicklungsserver muss dann auf dem Port 4000 laufen.
Siehe
Tests laufen lassen
cd "$PROJ_DIR" npm test
Projekt bauen
cd "$PROJ_DIR" npm run build
create-react-app, TypeScript und WebWorkers
Wenn man seine mit create-react-app --template typescript
erstellte Web-Applikation um Multithreading via Web Workers erweitern möchte, stellt sich das Problem, dass die Webpack-Konfiguration von create-react-app so komplex ist, dass man sie nicht anfassen möchte. Eine Änderung hätte auch Probleme mit dem Update der react-scripts zur Folge.
In Webpack v5 wird durch das URL-Handling von Webpack der Einsatz von TypeScript-WebWorkern mehr oder weniger einfach.
new Worker(new URL('./worker.js', import.meta.url));
Möglicherweise muss man in der tsconfig.json jedoch in compilerOptions.lib "webworker" ergänzt werden.
Siehe zu Webpack5 auch:
Bisher nutzt man in Webpack v4 die "!"-Syntax von Webpack für das Laden des worker-loader aus. So kann man vorgehen:
Installation von worker-loader
cd $PROJ_DIR npm install worker-loader --save-dev
Typdeklaration für Typescript
Erstellen der Datei $PROJ_DIR/src/typings/worker-loader.d.ts
mit folgendem Inhalt
declare module 'worker-loader!*' { // You need to change `Worker`, if you specified a different value for the `workerType` option class WebpackWorker extends Worker { constructor(); } // Uncomment this if you set the `esModule` option to `false` // export = WebpackWorker; export default WebpackWorker; }
Worker selbst
Erstellen der Datei $PROJ_DIR/src/my.worker.ts
mit folgendem Inhalt[2]
// Dieses Import-Statement ist nur notwendig, um dem Typescript-Transpiler mitzuteilen, dass // es sich hier auch um ein Module handelt. Es kann durch beliebige andere Imports ersetzt werden. import {} from "assert"; // eslint-disable-next-line no-restricted-globals const ctx: Worker = self as any; // Post data to parent thread ctx.postMessage({ foo: "foo" }); // Respond to message from parent thread ctx.addEventListener("message", (event) => { console.log("message from main thread:", event); ctx.postMessage({ orgData: event.data, now:new Date()}) });
Aufruf des Workers vom Main-Thread
Im Main-Thread, z.B. in $PROJ_DIR/src/App.tsx
kann man auf den Worker folgendermaßen zugreifen:
// eslint-disable-next-line import/no-webpack-loader-syntax import Worker from 'worker-loader!./my.worker'; const worker = new Worker(); worker.postMessage({ a: 1 }); worker.onmessage = (event) => { console.log ("message from worker:", event)};
Weiterhin: Problem mit Development-Server
Wenn weiterhin ein Problem mit dem Entwicklungsserver (npm run start
) besteht, hilft evtl. das Überschreiten der create-react-app-Konfiguration mit react-rewired:
- https://junghanns.it/posts/setup-workers-with-create-react-app-and-typescript/
- Möglicherweise muss man dabei auch an Babel denken.
Aber mit bestimmten Kniffen (z.B. Kopieren des Workers nach /public) kann man auch das Modifizieren der Konfiguration vermeiden:
pdf.js
Beim pdf.js-Worker hilft evtl. pdf.js nicht über pdfjs-dist, sondern über react-pdf einzubinden
npm install --save react-pdf npm install --save-dev @types/pdfjs-dist cp node_modules/pdfjs-dist/build/pdf.worker.js public/
Im TypeScript-Code müssen dann folgende Zeilen vorhanden sein:
import * as PDFJS from "pdfjs-dist";
PDFJS.GlobalWorkerOptions.workerSrc = `${process.env.PUBLIC_URL}/pdf.worker.js`;
PDFJS.getDocument(...
WebWorker und NextJs
Siehe oben "create-react-app, TypeScript und WebWorkers".
Siehe auch
- https://github.com/vercel/next.js/tree/canary/examples/with-web-worker
- https://nextjs.org/docs/messages/webpack5
- https://github.com/koheitakumi/nextjs-typescript-comlink
WebWorker, WebAssembly and NextJs
Mit WebAssembly kann auch compilierter Rust-Code im Browser, auch als WebWorker, ausgeführt werden:
Siehe https://medium.com/lagierandlagier/nextjs-webassembly-and-web-workers-a5f7c19d4fd0
Troubleshooting
Wenn zu wenig "Handles" für inotify-Überwachung durch den "Kompilierer" webpack oder die Testengine "Jest" zur Verfügung stehen, muss man Linux auf die Sprünge helfen:[3]
Man füge mit Root-Rechten folgende Zeile an die /etc/sysctl.conf
:
fs.inotify.max_user_watches=524288
Neuladen durch
sudo sysctl -p
- ↑ Vgl. https://medium.com/byteconf/getting-started-with-typescript-in-create-react-app-2306b713088f
- ↑ Vgl. https://www.npmjs.com/package/worker-loader - es wurde ein import-Statement hinzugefügt.
- ↑ Vgl. https://code.visualstudio.com/docs/setup/linux#_visual-studio-code-is-unable-to-watch-for-file-changes-in-this-large-workspace-error-enospc