React 和 TypeScript 是用於建立可擴展、可維護和安全網站的強大框架。 React 提供了靈活且基於元件的架構,而 TypeScript 則為 JavaScript 添加了靜態類型,以實現乾淨且可讀的程式碼。本文將引導您使用 React 和 TypeScript 設定一個簡單的網站,涵蓋入門所需的核心概念。
TypeScript 在 JavaScript 開發人員中很受歡迎,因為它可以在開發過程中捕獲錯誤並使程式碼更易於理解和重構。這兩者非常適合建立現代、快速的網站和應用程序,並具有可擴展的可維護程式碼。
** 在 GitHub 上查看完整程式碼:https://github.com/alexiacismaru/techtopia/tree/main/frontend
讓我們為一個名為 Techtopia 的虛構遊樂園建立一個網站。我們將顯示景點等元素以及它們在地圖上的位置、登陸頁面或載入頁面。此外,我們還將允許新增/刪除頁面元素或基於變數搜尋它們。
透過將其複製到終端機來建立一個空的 React 專案。
npm create vite@latest reactproject --template react-ts
然後執行空項目,瀏覽器視窗中將開啟一個新分頁。
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
元件是也可以重複使用的網頁元素。它們可以是網頁的一部分,例如頁首或頁腳,也可以是整個頁面,例如使用者清單。它就像一個 JavaScript 函數,但傳回一個渲染的元素。
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 是包含 JSX 語法的 TypeScript 檔案的檔案副檔名。借助 TSX,您可以使用現有的 JSX 語法編寫經過類型檢查的程式碼。
interface RefreshmentStand { id: string; name: string; isOpen: boolean; } const Reshfresment = (props: RefreshmentStand) => { return ( <div> <h1>{props.name}</h1> <p>{props.isOpen}</p> </div> ); };
片段將多個元素傳回組件。它會對元素清單進行分組,而不建立額外的 DOM 節點。
我們可以使用它們從Java 後端獲取資料(看看如何從本文建立Java 應用程式:https://medium.com/@alexia.csmr/using-bounded-contexts-to-build -a-java- application-1c7995038d30)。首先安裝 Axios 並使用應用程式中的基本後端 URL。然後,我們將創建一個使用 GET 獲取所有景點的片段。
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>
可以擴展到根據參數取得數據,POST,DELETE等
npm create vite@latest reactproject --template react-ts
狀態是一個 React 對象,包含有關組件的資料或資訊。元件的狀態可能會隨著時間的推移而變化,當發生變化時,元件會重新渲染。
要根據參數從清單中取得單一元素,您可以使用 useParams() 掛鉤。
cd reactproject npm run dev
如上所示,我使用了_useAttractions()和_useTagsAttractions()。它們是鉤子,可以進行個性化以獲得您想要的任何數據。在此範例中,他們根據 ID _或 _tags 取得景點。 Hooks 只能在 React 函數元件內部調用,只能在元件的頂層調用,且不能是有條件的。
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
為了獲得更好的 UI 體驗,最好讓使用者知道發生了什麼,即元素正在加載,或執行此操作時出現錯誤。它們首先在鉤子中聲明,然後在組件中引入。
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>
您也可以為更自訂的網站建立單獨的載入器或警報元件。
interface RefreshmentStand { id: string; name: string; isOpen: boolean; } const Reshfresment = (props: RefreshmentStand) => { return ( <div> <h1>{props.name}</h1> <p>{props.isOpen}</p> </div> ); };
現在,當頁面載入時,使用者將在螢幕上看到特殊的動畫。
如果你想顯示清單中的所有元素,那麼你需要映射所有元素。
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>
您可以在此處建立一個類型,以便稍後使用表單添加更多景點:
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>
我們已經創建了所需的片段和掛鉤,因此現在我們可以製作一個表單,使用者可以在其中寫入屬性並向網頁添加新的吸引力。此表單是使用 MUI 框架建立的。首先我將展示整個程式碼並分段解釋。
const { id } = useParams() const { isLoading, isError, attraction } = useAttraction(id!) const { tag } = useParams() const { isLoadingTag, isErrorTag, attractions } = useTagsAttractions(tag!)
如果您想讓表單成為彈出視窗而不是單獨的頁面,請新增 isOpen() 和 isClosed() 屬性。 onSubmit() 是強制性的,因為這將觸發 createPOI() 函數並將新物件新增至清單。
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>
為了進行使用者表單驗證,我們將安裝並匯入 Zod。在這裡聲明輸入需要什麼格式以及是否有最小或最大長度等要求。
const navigate = useNavigate() const { isLoading, isError, attractions, addAttraction } = useAttractions() if (isLoading) { return <loader></loader> } if (isError) { return <alert severity="error">Error</alert> }
在元件內部,我們需要實作提交和使用者驗證。
export default function Loader() { return ( <div> <img alt="如何使用 React 和 Rest API 建立網站(React 基礎知識解釋)" src="https://media0.giphy.com/media/RlqidJHbeL1sPMDlhZ/giphy.gif?cid=6c09b9522vr2magrjgn620u5mfz1ymnqhpvg558dv13sd0g8&ep=v1_stickers_related&rid=giphy.gif&ct=s"> <h3>Loading...</h3> </div> ) }
錯誤將在表單的 TextField 中與任何其他屬性一起實作。
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; }
確保表單可以在開始時關閉並提交。
export type CreatePOI = Omit<poi>; # id is automatically generated so we don't need to manually add it </poi>
您可以在另一個元件中實現此彈出視窗。
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>
建立一個使用 DELETE 的鉤子並在元件中實現它。
npm create vite@latest reactproject --template react-ts
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
將 React 與 TypeScript 結合使用可讓您建立易於維護和擴展的動態、安全的網站。 TypeScript 的類型檢查可以防止執行階段錯誤,而 React 基於元件的結構可以有效地組織專案。
以上是如何使用 React 和 Rest API 建立網站(React 基礎知識解釋)的詳細內容。更多資訊請關注PHP中文網其他相關文章!