Heim > Artikel > Web-Frontend > So erstellen Sie eine Website mit React- und Rest-APIs (React-Grundlagen erklärt)
React und TypeScript sind leistungsstarke Frameworks zum Erstellen skalierbarer, wartbarer und sicherer Websites. React bietet eine flexible und komponentenbasierte Architektur, während TypeScript statische Typisierung zu JavaScript hinzufügt, um sauberen und lesbaren Code zu erhalten. Dieser Artikel führt Sie durch die Einrichtung einer einfachen Website mit React und TypeScript und behandelt die Kernkonzepte, die für den Einstieg erforderlich sind.
TypeScript ist bei JavaScript-Entwicklern beliebt, da es Fehler während der Entwicklung erkennen und Code leichter verständlich und umgestaltbar machen kann. Die beiden eignen sich ideal zum Erstellen moderner, schneller Websites und Anwendungen mit wartbarem Code, der sich gut skalieren lässt.
** Schauen Sie sich den gesamten Code auf GitHub an: https://github.com/alexiacismaru/techtopia/tree/main/frontend
Lassen Sie uns eine Website für einen fiktiven Vergnügungspark namens Techtopia erstellen. Wir zeigen Elemente wie Attraktionen und deren Position auf der Karte, einer Landingpage oder einer Ladeseite an. Darüber hinaus ermöglichen wir auch das Hinzufügen/Löschen von Elementen der Seite oder die Suche nach ihnen basierend auf einer Variablen.
Erstellen Sie ein leeres React-Projekt, indem Sie es in das Terminal kopieren.
npm create vite@latest reactproject --template react-ts
Führen Sie dann das leere Projekt aus und ein neuer Tab wird im Browserfenster geöffnet.
cd reactproject npm run dev
reactproject/ ├── node_modules/ ├── public/ ├── src/ │ ├── assets/ │ ├── components/ │ ├── context/ │ ├── hooks/ │ ├── model/ │ ├── services/ │ ├── App.css │ ├── App.tsx │ ├── index.css │ ├── vite-env.d.ts ├── .gitignore ├── package.json └── tsconfig.json
Komponenten sind Elemente einer Webseite, die auch wiederverwendet werden können. Sie können ein Teil der Webseite sein, z. B. die Kopf- oder Fußzeile, oder die gesamte Seite, z. B. eine Benutzerliste. Es ähnelt einer JavaScript-Funktion, gibt jedoch ein gerendertes Element zurück.
export function Header() { return ( <header> <h3> JSX </h3> <p>JSX is JavaScript XML, allowing the user to write HTML-like code in .jsx files.<br> </p> <pre class="brush:php;toolbar:false"><button sx="{{padding:" color: onclick="{onClose}">X</button>
TSX ist eine Dateierweiterung für TypeScript-Dateien, die JSX-Syntax enthält. Mit TSX können Sie typgeprüften Code mit der vorhandenen JSX-Syntax schreiben.
interface RefreshmentStand { id: string; name: string; isOpen: boolean; } const Reshfresment = (props: RefreshmentStand) => { return ( <div> <h1>{props.name}</h1> <p>{props.isOpen}</p> </div> ); };
Fragmente geben mehrere Elemente an eine Komponente zurück. Es gruppiert die Liste der Elemente, ohne zusätzliche DOM-Knoten zu erstellen.
Wir können sie verwenden, um die Daten von einem Java-Backend abzurufen (lesen Sie in diesem Artikel, wie Sie die Java-Anwendung erstellen: https://medium.com/@alexia.csmr/using-bounded-contexts-to-build -a-java-application-1c7995038d30). Beginnen Sie mit der Installation von Axios und verwenden Sie die Basis-Backend-URL Ihrer Anwendung. Dann erstellen wir ein Fragment, das GET verwendet, um alle Attraktionen abzurufen.
import axios from 'axios' import { POI } from '../model/POI' const BACKEND_URL = 'http://localhost:8093/api' export const getAttractions = async () => { const url = BACKEND_URL + '/attractions' const response = await axios.get<poi>(url) return response.data } </poi>
Dies kann erweitert werden, um Daten basierend auf Parametern, POST, DELETE usw. abzurufen.
npm create vite@latest reactproject --template react-ts
Der Status ist ein React-Objekt, das Daten oder Informationen über die Komponente enthält. Der Zustand einer Komponente kann sich im Laufe der Zeit ändern und wenn dies der Fall ist, wird die Komponente neu gerendert.
Um ein einzelnes Element aus einer Liste basierend auf einem Parameter abzurufen, können Sie den Hook useParams() verwenden.
cd reactproject npm run dev
Wie oben gesehen, habe ich_ useAttractions() und _useTagsAttractions() verwendet. Sie sind Hooks und können personalisiert werden, um alle gewünschten Daten zu erhalten. In diesem Beispiel rufen sie die Attraktionen basierend auf ihrer ID _or _tags ab. Hooks können nur innerhalb von React-Funktionskomponenten aufgerufen werden, können nur auf der obersten Ebene einer Komponente aufgerufen werden und können nicht bedingt sein.
reactproject/ ├── node_modules/ ├── public/ ├── src/ │ ├── assets/ │ ├── components/ │ ├── context/ │ ├── hooks/ │ ├── model/ │ ├── services/ │ ├── App.css │ ├── App.tsx │ ├── index.css │ ├── vite-env.d.ts ├── .gitignore ├── package.json └── tsconfig.json
Für ein besseres UI-Erlebnis ist es gut, den Benutzer darüber zu informieren, was gerade passiert, z. B. ob die Elemente geladen werden oder ob beim Laden ein Fehler aufgetreten ist. Sie werden zuerst im Hook deklariert und dann in der Komponente eingeführt.
export function Header() { return ( <header> <h3> JSX </h3> <p>JSX is JavaScript XML, allowing the user to write HTML-like code in .jsx files.<br> </p> <pre class="brush:php;toolbar:false"><button sx="{{padding:" color: onclick="{onClose}">X</button>
Sie können auch eine separate Loader- oder Alert-Komponente für eine individuellere Website erstellen.
interface RefreshmentStand { id: string; name: string; isOpen: boolean; } const Reshfresment = (props: RefreshmentStand) => { return ( <div> <h1>{props.name}</h1> <p>{props.isOpen}</p> </div> ); };
Jetzt sieht der Benutzer beim Laden der Seite eine spezielle Animation auf dem Bildschirm.
Wenn Sie alle Elemente in einer Liste anzeigen möchten, müssen Sie sie alle zuordnen.
import axios from 'axios' import { POI } from '../model/POI' const BACKEND_URL = 'http://localhost:8093/api' export const getAttractions = async () => { const url = BACKEND_URL + '/attractions' const response = await axios.get<poi>(url) return response.data } </poi>
Mehr hier können Sie einen Typ erstellen, um später über ein Formular weitere Attraktionen hinzuzufügen:
export const addAttraction = async (attractionData: Omit<poi>) => { const url = BACKEND_URL + '/addAttraction' const response = await axios.post(url, attractionData) return response.data } export const getAttraction = async (attractionId: string) => { const url = BACKEND_URL + '/attractions' const response = await axios.get<poi>(`${url}/${attractionId}`) return response.data } export const getAttractionByTags = async (tags: string) => { const url = BACKEND_URL + '/attractions' const response = await axios.get<poi>(`${url}/tags/${tags}`) return response.data } </poi></poi></poi>
Wir haben bereits die dafür benötigten Fragmente und Hooks erstellt, sodass wir jetzt ein Formular erstellen können, in das der Benutzer die Attribute schreiben und der Webseite eine neue Attraktion hinzufügen kann. Dieses Formular wurde mit dem MUIframework erstellt. Zuerst zeige ich den gesamten Code und erkläre ihn in Abschnitten.
const { id } = useParams() const { isLoading, isError, attraction } = useAttraction(id!) const { tag } = useParams() const { isLoadingTag, isErrorTag, attractions } = useTagsAttractions(tag!)
Wenn Sie das Formular als Popup statt als separate Seite erstellen möchten, fügen Sie die Attribute isOpen() und isClosed() hinzu. onSubmit() ist obligatorisch, da dadurch die Funktion createPOI() ausgelöst und ein neues Objekt zur Liste hinzugefügt wird.
import {useMutation, useQuery, useQueryClient} from '@tanstack/react-query' import {POI} from "../model/./POI.ts"; import { addAttraction, getAttractions } from '../services/API.ts' import { useContext } from 'react' export function useAttractions() { const queryClient = useQueryClient() const { isLoading: isDoingGet, isError: isErrorGet, data: attractions, } = useQuery({ queryKey: ['attractions'], queryFn: () => getAttractions(), }) const { mutate, isLoading: isDoingPost, isError: isErrorPost, } = useMutation((item: Omit<poi>) => addAttraction(item), { onSuccess: () => { queryClient.invalidateQueries(['attractions']) }, }); return { isLoading: isDoingGet || isDoingPost, isError: isErrorGet || isErrorPost, attractions: attractions || [], addAttraction: mutate } } </poi>
Zur Benutzerformularvalidierung installieren und importieren wir Zod. Geben Sie hier an, welches Format die Eingabe haben muss und ob es Anforderungen wie Mindest- oder Höchstlänge gibt.
const navigate = useNavigate() const { isLoading, isError, attractions, addAttraction } = useAttractions() if (isLoading) { return <loader></loader> } if (isError) { return <alert severity="error">Error</alert> }
Innerhalb der Komponente müssen wir die Übermittlung und die Benutzervalidierung implementieren.
export default function Loader() { return ( <div> <img alt="So erstellen Sie eine Website mit React- und Rest-APIs (React-Grundlagen erklärt)" src="https://media0.giphy.com/media/RlqidJHbeL1sPMDlhZ/giphy.gif?cid=6c09b9522vr2magrjgn620u5mfz1ymnqhpvg558dv13sd0g8&ep=v1_stickers_related&rid=giphy.gif&ct=s"> <h3>Loading...</h3> </div> ) }
Die Fehler werden im TextField des Formulars mit allen anderen Attributen implementiert.
import { useState } from 'react' import { useNavigate } from 'react-router-dom' import { useAttractions } from '../hooks/usePOI.ts' import { POI } from '../model/./POI.ts' export default function Attractions() { const navigate = useNavigate() const { isLoading, isError, attractions, addAttraction } = useAttractions() return ( <div> <p>Create a separate file where you declare the Attraction element and its variables.<br> </p> <pre class="brush:php;toolbar:false">// ../model/POI.ts export interface POI { id: string; name: string; description: string; tags: string; ageGroup: string; image: string; }
Stellen Sie sicher, dass das Formular am Anfang geschlossen und abgesendet werden kann.
export type CreatePOI = Omit<poi>; # id is automatically generated so we don't need to manually add it </poi>
Sie können dieses Popup in einer anderen Komponente implementieren.
import {CreatePOI} from "../model/./POI.ts"; import {z} from 'zod'; import {zodResolver} from "@hookform/resolvers/zod"; import {Controller, useForm} from "react-hook-form"; import { Box, Button, Dialog, DialogActions, DialogContent, DialogTitle, TextField, } from '@mui/material' interface AttractionDialogProps { isOpen: boolean; onSubmit: (attraction: CreatePOI) => void; onClose: () => void; } const itemSchema: z.ZodType<createpoi> = z.object({ name: z.string().min(2, 'Name must be at least 2 characters'), description: z.string(), tags: z.string(), ageGroup: z.string(), image: z.string().url(), }) export function AddAttractionDialog({isOpen, onSubmit, onClose}: AttractionDialogProps) { const { handleSubmit, control, formState: {errors}, } = useForm<createpoi>({ resolver: zodResolver(itemSchema), defaultValues: { name: '', description: '', tags: '', ageGroup: '', image: '', }, }); return ( <dialog open="{isOpen}" onclose="{onClose}"> <form onsubmit="{handleSubmit((data)"> { onSubmit(data) onClose() })} > <div> <dialogtitle>Add attraction</dialogtitle> <button onclick="{onClose}"> X </button> </div> <dialogcontent> <box> <controller name="name" control="{control}" render="{({field})"> ( <textfield label="Name" error="{!!errors.name}" helpertext="{errors.name?.message}" required></textfield> )} /> <controller name="description" control="{control}" render="{({field})"> ( <textfield label="Description" error="{!!errors.description}" helpertext="{errors.description?.message}"></textfield> )} /> <controller name="tags" control="{control}" render="{({field})"> ( <textfield label="Tags" error="{!!errors.tags}" helpertext="{errors.tags?.message}" required></textfield> )} /> <controller name="ageGroup" control="{control}" render="{({field})"> ( <textfield label="Age group" error="{!!errors.ageGroup}" helpertext="{errors.ageGroup?.message}" required></textfield> )} /> <controller name="image" control="{control}" render="{({field})"> ( <textfield label="Image" error="{!!errors.image}" helpertext="{errors.image?.message}" required></textfield> )} /> </controller></controller></controller></controller></controller></box> </dialogcontent> <dialogactions> <button type="submit" variant="contained"> Add </button> </dialogactions> </form> </dialog> ) } </createpoi></createpoi>
Erstellen Sie einen Hook, der DELETE verwendet, und implementieren Sie ihn in einer Komponente.
npm create vite@latest reactproject --template react-ts
cd reactproject npm run dev
Beziehen Sie es ein, wenn Sie die Liste der Elemente durchlaufen.
reactproject/ ├── node_modules/ ├── public/ ├── src/ │ ├── assets/ │ ├── components/ │ ├── context/ │ ├── hooks/ │ ├── model/ │ ├── services/ │ ├── App.css │ ├── App.tsx │ ├── index.css │ ├── vite-env.d.ts ├── .gitignore ├── package.json └── tsconfig.json
Durch die Verwendung von React mit TypeScript können Sie dynamische, sichere Websites erstellen, die einfach zu warten und zu skalieren sind. Die Typprüfung von TypeScript verhindert Laufzeitfehler, während die komponentenbasierte Struktur von React das Projekt effizient organisiert.
Das obige ist der detaillierte Inhalt vonSo erstellen Sie eine Website mit React- und Rest-APIs (React-Grundlagen erklärt). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!