| Zeile 7: |
Zeile 7: |
| | Siehe | | Siehe |
| | * [https://www.robinwieruch.de/react-pass-props-to-component/ Vertiefung der React Props] - ausführlich unter Berücksichtigung neuerer JavaScript-Sprachkonstrukte | | * [https://www.robinwieruch.de/react-pass-props-to-component/ Vertiefung der React Props] - ausführlich unter Berücksichtigung neuerer JavaScript-Sprachkonstrukte |
| | + | |
| | + | === React Native === |
| | + | |
| | + | Seihe [[React Native]] |
| | | | |
| | == Projektstruktur == | | == Projektstruktur == |
| | | | |
| | React gibt keine Projektstruktur vor. Mit Hilfe von [https://github.com/facebook/create-react-app 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. | | React gibt keine Projektstruktur vor. Mit Hilfe von [https://github.com/facebook/create-react-app 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 |
| | + | * https://blog.codecentric.de/2019/05/web-anwendungen-mit-node-express-typescript-entwickeln/ |
| | + | |
| | + | Siehe für eine Projektstruktur mit [[zustand]] und [[Next.js]]: |
| | + | * https://medium.com/@itsspss/large-scale-react-zustand-nest-js-project-structure-and-best-practices-93397fb473f4 |
| | + | |
| | + | === Alternative zu create-react-app === |
| | + | |
| | + | Einen schnelleren Build-Prozess als create-react-app aufgrund des eingesetzten esbuild-Tools verspricht Vite. |
| | + | |
| | + | * [https://dev.to/nilanth/use-vite-for-react-apps-instead-of-cra-3pkg nilanth zeigt u.a. den Migrationsprozess von CRA zu 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 |
| | + | * https://stackoverflow.com/questions/43011207/using-homepage-in-package-json-without-messing-up-paths-for-localhost |
| | | | |
| | == React und TypeScript und Webpack == | | == React und TypeScript und Webpack == |
| − | | + | === Allgemeines === |
| | Siehe | | Siehe |
| | * Codeburst on webpack typescript and react | | * Codeburst on webpack typescript and react |
| | ** https://codeburst.io/webpack-typescript-react-part-1-dc154e250f23 | | ** https://codeburst.io/webpack-typescript-react-part-1-dc154e250f23 |
| | ** https://codeburst.io/webpack-typescript-react-part-3-82ce3000d25e | | ** https://codeburst.io/webpack-typescript-react-part-3-82ce3000d25e |
| | + | |
| | + | === 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) |
| | + | * [https://github.com/stereobooster/react-snap react-snap] - arbeitet mit einem Headless Chrome im Build-Prozess |
| | + | * [https://github.com/dzianisbohush/cra-with-ssr cra-with-ssr Anleitung zu SSR mit Hydration auf Basis von CRA] |
| | + | * [https://razzlejs.org/docs/static-export Razzle] |
| | + | * umfangreichere Frameworks |
| | + | ** Next.js |
| | + | ** Vite |
| | + | ** [https://remix.run/ Remix] |
| | + | ** [https://www.gatsbyjs.com/ Gatsby] |
| | + | *** https://medium.com/@thetrevorharmon/how-to-make-a-super-fast-static-site-with-gatsby-typescript-and-sass-3742c00d4524 |
| | + | |
| | + | 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://www.typescriptlang.org/docs/handbook/react-&-webpack.html |
| | * https://medium.com/better-programming/react-redux-with-typescript-7ff678bc17ab | | * 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 |
| | + | * [https://github.com/piotrwitek/react-redux-typescript-guide Kompendium zu React, TypeScript und Redux] |
| | + | * [https://medium.com/@dhruvrajvanshi/some-tips-on-type-safety-with-redux-98588a85604c Vorschlag einer Best Practice für Typensicherheit mit Redux und React] |
| | + | |
| | + | === Leichtgewichtige Alternativen === |
| | + | |
| | + | ==== Eigene (custom) react hooks ==== |
| | + | |
| | + | Siehe |
| | + | * [https://blog.logrocket.com/react-hooks-with-firebase-firestore/ 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 [https://www.npmjs.com/package/global-hook-store 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 <code>package.json</code> Folgendes aufzunehmen: |
| | + | <pre> |
| | + | |
| | + | "jest": { |
| | + | "transformIgnorePatterns": [ |
| | + | "/node_modules/(?!global-hook-store).+\\.js$" |
| | + | ] |
| | + | }, |
| | + | </pre> |
| | + | |
| | + | ==== 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 |
| | + | * https://recoiljs.org/ |
| | + | |
| | + | |
| | + | ==== Jotai ==== |
| | + | |
| | + | Siehe |
| | + | |
| | + | * https://github.com/pmndrs/jotai |
| | | | |
| | == Testen von React == | | == Testen von React == |
| Zeile 32: |
Zeile 121: |
| | | | |
| | Siehe | | Siehe |
| | + | * [https://www.npmjs.com/package/react-window react-window], Nachfolger von react-virtualized |
| | * [https://itnext.io/handling-large-lists-and-tables-in-react-238397854625 Lange Listen darstellen während des Ladens] | | * [https://itnext.io/handling-large-lists-and-tables-in-react-238397854625 Lange Listen darstellen während des Ladens] |
| | * [https://stackoverflow.com/questions/38033442/big-list-performance-with-react Darstellen langer Listen mit React] | | * [https://stackoverflow.com/questions/38033442/big-list-performance-with-react Darstellen langer Listen mit React] |
| Zeile 37: |
Zeile 127: |
| | | | |
| | == Ergänzungen für React == | | == 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 |
| | + | * [https://www.npmjs.com/package/react-query-params React-Query-Params] lässt mit den URI-Parametern ähnlich umgehen wie mit State oder Props. |
| | + | |
| | === Komponenten === | | === Komponenten === |
| | | | |
| | ==== Rich Text Editor ==== | | ==== Rich Text Editor ==== |
| | | | |
| − | * Der CKEditor unterstützt u.a. Tabellen. Ihn gibt es auch in einem React-Geschmack. | + | * [https://editorjs.io/ editor.js] |
| | + | ** kann auch [https://www.npmjs.com/package/@editorjs/table Tabellen] |
| | + | ** kann auch in [https://github.com/editor-js/awesome-editorjs?tab=readme-ov-file#react React eingebettet] werden |
| | + | |
| | + | * [https://github.com/ianstormtaylor/slate Slate] |
| | + | * [https://craft.js.org/r/docs/guides/basic-tutorial Craft.js] |
| | + | |
| | + | * Der CKEditor unterstützt u.a. Tabellen. |
| | + | ** Ihn gibt es auch in einem [https://ckeditor.com/docs/ckeditor5/latest/builds/guides/integration/frameworks/react.html React-Geschmack]. |
| | + | ** Der [https://alloyeditor.com/docs/features/tableheading.html AlloyEditor] macht sich Mühe, ihn mit kontextsensitiven Menüs auszugestalten. |
| | + | * Den [https://www.tiny.cloud/pricing TinyMCE] gibt es in einer Open Source- und verschiedenen kommerziellen Varianten. |
| | + | ** [https://www.tiny.cloud/docs/integrations/react/ TinyMCE-React Integration] |
| | + | * [https://xdsoft.net/jodit/ Jodit] kann auch [https://xdsoft.net/jodit/play.html Tabellen]. |
| | + | ** https://github.com/jodit/jodit-react (MIT Lizenz) |
| | + | * https://github.com/mkhstar/suneditor-react |
| | + | * https://github.com/summernote/summernote |
| | + | ** https://github.com/summernote/react-summernote |
| | + | * https://www.npmjs.com/package/react-editor-js unterstützt auch einfache Tabellen |
| | + | |
| | + | * [https://react-page.github.io/ React Page] hat wohl keine Tabellen. |
| | + | * https://github.com/zenoamaro/react-quill hat wohl keine Tabellen. |
| | + | |
| | + | * https://github.com/quilljs/quill |
| | + | ** https://github.com/quilljs/quill |
| | + | ** https://github.com/zenoamaro/react-quill |
| | + | |
| | + | ==== Tabellenbearbeitung ==== |
| | + | |
| | + | Komponenten zur Nutzung in React als Editor für die Bearbeitung von Tabellen ähnlich [[Excel]]: |
| | + | |
| | + | * [https://www.ag-grid.com/react-data-grid/getting-started/ AG Grid] |
| | + | * [https://github.com/TanStack/table TanStack] |
| | + | * [https://github.com/handsontable/handsontable?tab=readme-ov-file Handsontable] |
| | + | * Plugins für Editor.js: |
| | + | ** [https://github.com/codinova-tech/editorjs-table editorjs-table], keine Formeln |
| | + | ** [https://github.com/editor-js/table editor-js/table], keine Formeln |
| | + | * [https://github.com/nick-keller/react-datasheet-grid React-Datasheet-Grid], wohl keine Formeln |
| | + | * [https://github.com/dream-num/univer Univer] - muss noch geprüft werden, ob innerhalb React einsetzbar; freie Version hat [https://univer.ai/en-US/pricing Einschränkungen] |
| | + | * [https://github.com/olifolkerd/tabulator?tab=readme-ov-file Tabulator] |
| | + | * [https://docs.sheetjs.com/docs/demos/frontend/react SheetJS] |
| | + | * [https://github.com/silevis/reactgrid ReactGrid] - wohl keine Formeln |
| | + | * [https://github.com/future-architect/cheetah-grid Cheetah Grid], wohl keine Formeln |
| | + | * [https://github.com/myliang/x-spreadsheet x-spreadsheet] - still maintained? |
| | + | |
| | + | |
| | + | Bloße Spreadsheet-Engine ohne UI (headless): |
| | + | * [https://github.com/handsontable/hyperformula HyperFormula] |
| | + | |
| | + | Kommerziell: |
| | + | * https://dhtmlx.com/docs/products/dhtmlxSpreadsheet/ |
| | + | ** Community Edition ist verfügbar (GPL v2.0) |
| | + | * [https://ej2.syncfusion.com/demos/?_gl=1*qzjtti*_gcl_au*MTI4NjYwNjc2Mi4xNzMyNjI2Mzgy*_ga*MTc2NTQwMzM5Mi4xNzMyNjI2Mzgy*_ga_41J4HFMX1J*MTczMzQxNDc2MC4yLjEuMTczMzQxNDk1OS4wLjAuMA..#/bootstrap5/spreadsheet/default.html syncFusion], mit Formeln, mit Verbinden von Zellen |
| | + | |
| | ==== Komponentensammlung ==== | | ==== Komponentensammlung ==== |
| | | | |
| − | * [https://www.primefaces.org/primereact/#/ PrimeReact] bietet ca. 70 UI-Komponenten. | + | * [https://primereact.org/ PrimeReact] bietet sehr viele UI-Komponenten. |
| | + | ** Das Schwesterprojekt [https://primeflex.org/ PrimeFlex] bietet CSS-Klassen. |
| | * [https://github.com/carbon-design-system/carbon/tree/master/packages/react IBM Carbon Desgin] | | * [https://github.com/carbon-design-system/carbon/tree/master/packages/react IBM Carbon Desgin] |
| | + | * [https://www.radix-ui.com/themes/playground Radix] benützt zumindest JSX, ist möglicherweise React-basiert |
| | + | * [https://ui.shadcn.com/ shadcn/ui] ist Radix-basiert. |
| | + | * [https://react.semantic-ui.com/ Semantic UI] |
| | + | ** https://www.npmjs.com/package/react-semantic-ui-datepickers |
| | + | * [https://fomantic-ui.com/ Fomantic-UI] - ein Open Source Fork von Semantic UI |
| | + | |
| | + | ==== Icons ==== |
| | + | |
| | + | * https://github.com/feathericons/feather bietet einfache Icons im SVG-Format unter MIT-Lizenz |
| | + | ** [https://feathericons.com/ Feather-Icon-Übersicht] |
| | + | ** react-feather |
| | + | * [https://ionic.io/ionicons Ionicons] mit MIT-Lizenz |
| | + | * [https://github.com/phosphor-icons/phosphor-icons Phosphor-Icons] sind ebenfalls unter der MIT-Lizenz |
| | + | ** [https://phosphoricons.com/ Phosphor-Icons-Übersicht] |
| | + | * [https://github.com/twbs/icons Bootstrap Icons] können unabhängig vom Rest von [[Bootstrap]] genutzt werden. |
| | + | ** https://icons.getbootstrap.com/ |
| | + | * [https://github.com/carbon-design-system/carbon/tree/master/packages/icons IBM Carbon Icons] mit Apache-Lizenz und React-Unterstützung |
| | + | ** [https://carbon-elements.netlify.app/icons/examples/preview/ Carbon Icon Übersicht] |
| | + | * [https://iconify.design/icon-sets/ Übersicht über verschiedene Icon-Sets] |
| | + | |
| | + | ==== Diagramme ==== |
| | + | |
| | + | * [https://airbnb.io/visx/gallery 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 === | | === Canvas und React === |
| | Siehe | | Siehe |
| | * [https://dev.to/ankursheel/react-component-to-fraw-on-a-page-using-hooks-and-typescript-2ahp Zeichenkomponente, die React Hooks verwendet] | | * [https://dev.to/ankursheel/react-component-to-fraw-on-a-page-using-hooks-and-typescript-2ahp Zeichenkomponente, die React Hooks verwendet] |
| | + | * [https://konvajs.org/docs/react/ Konvajs] ist eine objektorientierte Zeichenbibliothek für Canvas, die auch mit React integriert |
| | + | ** https://medium.com/better-programming/how-to-make-a-whiteboard-app-with-react-konva-8766a532a39f |
| | + | * https://react.rocks/tag/Canvas |
| | | | |
| | == Beispiel für TypeScript und React == | | == Beispiel für TypeScript und React == |
| Zeile 99: |
Zeile 276: |
| | cd "$PROJ_DIR" | | cd "$PROJ_DIR" |
| | npm start | | 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 <code>frontend/package.json</code> etwa folgende Zeile auf: |
| | + | |
| | + | "proxy": "http://localhost:4000" |
| | + | |
| | + | Der Entwicklungsserver muss dann auf dem Port 4000 laufen. |
| | + | |
| | + | Siehe |
| | + | * https://create-react-app.dev/docs/proxying-api-requests-in-development/ |
| | | | |
| | === Tests laufen lassen === | | === Tests laufen lassen === |
| Zeile 108: |
Zeile 296: |
| | npm run build | | npm run build |
| | | | |
| | + | === create-react-app, TypeScript und WebWorkers === |
| | + | |
| | + | Wenn man seine mit <code>create-react-app --template typescript</code> 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 [https://github.com/webpack/webpack/discussions/13655 mehr oder weniger einfach]. |
| | + | new Worker(new URL('./worker.js', import.meta.url)); |
| | + | Möglicherweise muss man in der tsconfig.json jedoch [https://thewebdev.info/2022/03/21/how-to-make-web-workers-with-typescript-and-webpack/ in compilerOptions.lib "webworker" ] ergänzt werden. |
| | + | |
| | + | Siehe zu Webpack5 auch: |
| | + | * https://blog.logrocket.com/web-workers-react-typescript/ |
| | + | |
| | + | 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 <code>$PROJ_DIR/src/typings/worker-loader.d.ts</code> 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 <code>$PROJ_DIR/src/my.worker.ts</code> mit folgendem Inhalt<ref>Vgl. https://www.npmjs.com/package/worker-loader - es wurde ein import-Statement hinzugefügt.</ref> |
| | + | <pre> |
| | + | // 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()}) |
| | + | }); |
| | + | </pre> |
| | + | |
| | + | ==== Aufruf des Workers vom Main-Thread ==== |
| | + | |
| | + | Im Main-Thread, z.B. in <code>$PROJ_DIR/src/App.tsx</code> kann man auf den Worker folgendermaßen zugreifen: |
| | + | |
| | + | <pre> |
| | + | // 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)}; |
| | + | </pre> |
| | + | |
| | + | ==== Weiterhin: Problem mit Development-Server ==== |
| | + | |
| | + | Wenn weiterhin ein Problem mit dem Entwicklungsserver (<code>npm run start</code>) 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 [https://github.com/webpack-contrib/worker-loader/issues/35#issuecomment-571034338 an Babel denken]. |
| | + | |
| | + | Aber mit bestimmten Kniffen (z.B. Kopieren des Workers nach /public) kann man auch das Modifizieren der Konfiguration vermeiden: |
| | + | * https://github.com/webisora/displaying-pdf-using-react |
| | + | |
| | + | ===== 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://github.com/vercel/next.js/blob/canary/examples/with-web-worker/pages/index.tsx |
| | + | * 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 === | | === Troubleshooting === |
| | | | |