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를 기준으로 명소를 가져옵니다. 후크는 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>
이미 필요한 프래그먼트와 후크를 만들었으므로 이제 사용자가 속성을 작성하고 웹페이지에 새로운 매력을 추가할 수 있는 양식을 만들 수 있습니다. 이 양식은 MUIframework를 사용하여 만들어졌습니다. 먼저 전체 코드를 보여드리고 섹션별로 설명하겠습니다.
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 중국어 웹사이트의 기타 관련 기사를 참조하세요!