如何使用 React 和 Rest API 构建网站(React 基础知识解释)
大家好,今天本人给大家带来文章《如何使用 React 和 Rest API 构建网站(React 基础知识解释)》,文中内容主要涉及到,如果你对文章方面的知识点感兴趣,那就请各位朋友继续看下去吧~希望能真正帮到你们,谢谢!

react 和 typescript 是用于构建可扩展、可维护和安全网站的强大框架。 react 提供了灵活且基于组件的架构,而 typescript 在 javascript 中添加了静态类型,以实现干净且可读的代码。本文将指导您使用 react 和 typescript 设置一个简单的网站,涵盖入门所需的核心概念。
为什么选择 react 和 typescript?
typescript 在 javascript 开发人员中很受欢迎,因为它可以在开发过程中捕获错误并使代码更易于理解和重构。两者非常适合构建现代、快速的网站和应用程序,并具有可扩展的可维护代码。
** 在 github 上查看完整代码:https://github.com/alexiacismaru/techtopia/tree/main/frontend
基本的 react 概念以及如何使用它们来构建网站
让我们为一个名为 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 style={{ display: 'block', width: '100%', top: 0, left: 0, zindex: 'var(--header-and-footer)' }}>
<div style={{
borderbottom: '1px solid white',
boxshadow: '',
backgroundcolor: 'transparent',
paddingleft: '1rem',
paddingright: '1rem',
marginleft: 'auto',
marginright: 'auto',
}}>
<div
style={{
display: 'flex',
justifycontent: 'space-between',
padding: '5px',
alignitems: 'baseline',
}}
>
<a href='/techtopia' style={{
fontsize: '40px', fontfamily: 'marolla__', color: 'black',
fontweight: 'bold',
}}>techtopia</a>
<div style={{display: 'flex',
justifycontent: 'space-around',
padding: '5px',
alignitems: 'baseline',}}>
<a href='/refreshment-stands' style={{
marginright: '10px', color: 'black'
}}>refreshment stands</a>
<a href='/attractions' style={{ marginright: '10px', color: 'white'
}}>attractions</a>
<a href='/map' style={{ marginright: '60px', color: 'white'
}}>map</a>
</div>
</div>
</div>
</header>
)
}
jsx
jsx 是 javascript xml,允许用户在 .jsx 文件中编写类似 html 的代码。
<button sx={{padding: "10px", color: 'black'}} 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
}
可以扩展到根据参数获取数据,post,delete等
export const addattraction = async (attractiondata: omit<poi, 'id'>) => {
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
}
状态
状态是一个 react 对象,包含有关组件的数据或信息。组件的状态可能会随着时间的推移而发生变化,当发生变化时,组件会重新渲染。
要根据参数从列表中获取单个元素,您可以使用 useparams() 挂钩。
const { id } = useparams()
const { isloading, iserror, attraction } = useattraction(id!)
const { tag } = useparams()
const { isloadingtag, iserrortag, attractions } = usetagsattractions(tag!)
挂钩
如上所示,我使用了_useattractions()和_usetagsattractions()。它们是钩子,可以进行个性化以获得您想要的任何数据。在此示例中,他们根据 id _或 _tags 获取景点。 hooks 只能在 react 函数组件内部调用,只能在组件的顶层调用,并且不能是有条件的。
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, 'id'>) => addattraction(item), {
onsuccess: () => {
queryclient.invalidatequeries(['attractions'])
},
});
return {
isloading: isdoingget || isdoingpost,
iserror: iserrorget || iserrorpost,
attractions: attractions || [],
addattraction: mutate
}
}
isloading 和 iserror
为了获得更好的 ui 体验,最好让用户知道发生了什么,即元素正在加载,或者执行此操作时出现错误。它们首先在钩子中声明,然后在组件中引入。
const navigate = usenavigate()
const { isloading, iserror, attractions, addattraction } = useattractions()
if (isloading) {
return <loader />
}
if (iserror) {
return <alert severity='error'>error</alert>
}
您还可以为更加自定义的网站创建单独的加载器或警报组件。
export default function loader() {
return (
<div>
<img alt="loading..."
src="https://media0.giphy.com/media/rlqidjhbel1spmdlhz/giphy.gif?cid=6c09b9522vr2magrjgn620u5mfz1ymnqhpvg558dv13sd0g8&ep=v1_stickers_related&rid=giphy.gif&ct=s"/>
<h3>loading...</h3>
</div>
)
}
现在,当页面加载时,用户将在屏幕上看到特殊的动画。
映射项目(列表和键)
如果你想显示列表中的所有元素,那么你需要映射所有元素。
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 style={{ margintop: '70px' }}>
{filteredattractions
.map(({ id, name, image }: poi) => (
<div onclick={() => navigate(`/attractions/${id}`)} >
<div>
<img src={image} alt={name}/>
<h3>{name}</h3>
</div>
</div>
))}
</div>
)
}
创建一个单独的文件,在其中声明 attraction 元素及其变量。
// ../model/poi.ts
export interface poi {
id: string;
name: string;
description: string;
tags: string;
agegroup: string;
image: string;
}
您可以在此处创建一个类型,以便稍后使用表单添加更多景点:
export type createpoi = omit<poi, 'id'>; # id is automatically generated so we don't need to manually add it
添加项目
我们已经创建了所需的片段和挂钩,因此现在我们可以制作一个表单,用户可以在其中写入属性并向网页添加新的吸引力。该表单是使用 mui 框架创建的。首先我将展示整个代码并分段解释。
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
{...field}
label="name"
error={!!errors.name}
helpertext={errors.name?.message}
required
/>
)}
/>
<controller
name="description"
control={control}
render={({field}) => (
<textfield
{...field}
label="description"
error={!!errors.description}
helpertext={errors.description?.message}
/>
)}
/>
<controller
name="tags"
control={control}
render={({field}) => (
<textfield
{...field}
label="tags"
error={!!errors.tags}
helpertext={errors.tags?.message}
required
/>
)}
/>
<controller
name="agegroup"
control={control}
render={({field}) => (
<textfield
{...field}
label="age group"
error={!!errors.agegroup}
helpertext={errors.agegroup?.message}
required
/>
)}
/>
<controller
name="image"
control={control}
render={({field}) => (
<textfield
{...field}
label="image"
error={!!errors.image}
helpertext={errors.image?.message}
required
/>
)}
/>
</box>
</dialogcontent>
<dialogactions>
<button type="submit" variant="contained">
add
</button>
</dialogactions>
</form>
</dialog>
)
}
如果您想让表单成为弹出窗口而不是单独的页面,请添加 isopen() 和 isclosed() 属性。 onsubmit() 是强制性的,因为这将触发 createpoi() 函数并将新对象添加到列表中。
interface attractiondialogprops {
isopen: boolean;
onsubmit: (attraction: createpoi) => void;
onclose: () => void;
}
为了进行用户表单验证,我们将安装并导入 zod。在这里声明输入需要什么格式以及是否有最小或最大长度等要求。
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(),
})
在组件内部,我们需要实现提交和用户验证。
const {
handlesubmit,
control,
formstate: {errors},
} = useform<createpoi>({
resolver: zodresolver(itemschema),
defaultvalues: {
name: '',
description: '',
tags: '',
agegroup: '',
image: '',
},
});
错误将在表单的 textfield 中与任何其他属性一起实现。
<textfield
{...field}
label="name"
error={!!errors.name}
helpertext={errors.name?.message}
required
/>
确保表单可以在开始时关闭并提交。
<dialog open={isopen} onclose={onclose}>
<form
onsubmit={handlesubmit((data) => {
onsubmit(data)
onclose()
})}
>
</form>
</dialog>
您可以在另一个组件中实现此弹出窗口。
import { fab } from '@mui/material'
import addicon from '@mui/icons-material/add'
<fab
size='large'
aria-label='add'
onclick={() => setisdialogopen(true)}
>
<addicon />
</fab>
删除项目
创建一个使用 delete 的钩子并在组件中实现它。
import { usemutation, usequery, usequeryclient } from '@tanstack/react-query'
import { deleterefreshmentstand, getrefreshmentstand } from '../services/api.ts'
import { usecontext } from 'react'
export function userefreshmentstanditem(refreshmentstandid: string) {
const queryclient = usequeryclient()
const {
isloading: isdoingget,
iserror: iserrorget,
data: refreshmentstand,
} = usequery({
querykey: ['refreshmentstand'],
queryfn: () => getrefreshmentstand(refreshmentstandid),
})
const deleterefreshmentstandmutation = usemutation(() => deleterefreshmentstand(refreshmentstandid), {
onsuccess: () => {
queryclient.invalidatequeries(['refreshmentstands']);
},
});
const handledeleterefreshmentstand = () => {
deleterefreshmentstandmutation.mutate(); // trigger the delete mutation
};
return {
isloading: isdoingget || deleterefreshmentstandmutation.isloading,
iserror: iserrorget || deleterefreshmentstandmutation.iserror,
refreshmentstand,
deleterefreshmentstand: handledeleterefreshmentstand,
};
}
export default function refreshmentstand() {
const { id } = useparams()
const { isloading, iserror, refreshmentstand, deleterefreshmentstand } = userefreshmentstanditem(id!)
if (isloading) {
return <loader />
}
if (iserror || !refreshmentstand) {
return <alert severity='error'>error</alert>
}
return (
<>
<cardmedia component='img' image={background} alt='background' />
<authheader />
<div style={{ display: 'flex', alignitems: 'center' }}>
<div>
<h1>{refreshmentstand.name}</h1>
<p>status: {refreshmentstand.isopen ? 'open' : 'closed'}</p>
/* implement the delete button */
<fab>
<deleteicon onclick={deleterefreshmentstand}/>
</fab>
</div>
<img src={refreshmentstand.image} alt='refreshmentstand image' />
</div>
<footer />
</>
)
}
过滤项目
在组件内部创建一个用于过滤文本输入的切换开关和一个根据年龄组或标签过滤景点的常量。可选链接 (?) 确保它处理 null 或未定义的值而不会出现错误。
const togglefilter = () => {
setisfilteropen(!isfilteropen)
}
const filteredattractions = attractions
.filter((attraction: poi) =>
attraction.agegroup?.tolowercase().includes(agegroupfilter.tolowercase()),
)
.filter((attraction: poi) =>
attraction.tags?.tolowercase().includes(tagsfilter.tolowercase()),
)
在迭代项目列表时包含它。
{filteredAttractions
.filter((attraction: POI) =>
searchText.trim() === '' ||
attraction.name.toLowerCase().includes(searchText.toLowerCase()),
)
.map(({ id, name, image }: POI) => (
<div>
<div>
<img
src={image}
alt={name}
/>
<h3>{name}</h3>
</div>
</div>
))}
结论
将 react 与 typescript 结合使用使您能够构建易于维护和扩展的动态、安全的网站。 typescript 的类型检查可以防止运行时错误,而 react 基于组件的结构可以有效地组织项目。
文中关于的知识介绍,希望对你的学习有所帮助!若是受益匪浅,那就动动鼠标收藏这篇《如何使用 React 和 Rest API 构建网站(React 基础知识解释)》文章吧,也可关注golang学习网公众号了解相关技术文章。
win10中怎么打开画图工具_win10中打开画图工具方法介绍
- 上一篇
- win10中怎么打开画图工具_win10中打开画图工具方法介绍
- 下一篇
- 揭秘电脑死机蓝屏故障的7大常见原因
-
- 文章 · 前端 | 7分钟前 | label标签 :checked伪类 自定义复选框单选框 CSS状态控制 隐藏原生控件
- 自定义单选复选框制作教程
- 463浏览 收藏
-
- 文章 · 前端 | 18分钟前 |
- DIV背景色不显示解决方法
- 228浏览 收藏
-
- 文章 · 前端 | 29分钟前 |
- CSS中rgb颜色设置方法详解
- 259浏览 收藏
-
- 文章 · 前端 | 36分钟前 |
- CSS图片响应式缩放技巧:手机适配实用方法
- 451浏览 收藏
-
- 文章 · 前端 | 39分钟前 |
- JavaScript数组对象空值检查技巧
- 451浏览 收藏
-
- 文章 · 前端 | 42分钟前 | CSS JavaScript 平滑滚动 自定义样式 滚动条动态效果
- HTML动态滚动条效果实现方法
- 200浏览 收藏
-
- 文章 · 前端 | 45分钟前 |
- CSS浮动溢出父容器怎么解决
- 306浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- ChatExcel酷表
- ChatExcel酷表是由北京大学团队打造的Excel聊天机器人,用自然语言操控表格,简化数据处理,告别繁琐操作,提升工作效率!适用于学生、上班族及政府人员。
- 3178次使用
-
- Any绘本
- 探索Any绘本(anypicturebook.com/zh),一款开源免费的AI绘本创作工具,基于Google Gemini与Flux AI模型,让您轻松创作个性化绘本。适用于家庭、教育、创作等多种场景,零门槛,高自由度,技术透明,本地可控。
- 3389次使用
-
- 可赞AI
- 可赞AI,AI驱动的办公可视化智能工具,助您轻松实现文本与可视化元素高效转化。无论是智能文档生成、多格式文本解析,还是一键生成专业图表、脑图、知识卡片,可赞AI都能让信息处理更清晰高效。覆盖数据汇报、会议纪要、内容营销等全场景,大幅提升办公效率,降低专业门槛,是您提升工作效率的得力助手。
- 3418次使用
-
- 星月写作
- 星月写作是国内首款聚焦中文网络小说创作的AI辅助工具,解决网文作者从构思到变现的全流程痛点。AI扫榜、专属模板、全链路适配,助力新人快速上手,资深作者效率倍增。
- 4523次使用
-
- MagicLight
- MagicLight.ai是全球首款叙事驱动型AI动画视频创作平台,专注于解决从故事想法到完整动画的全流程痛点。它通过自研AI模型,保障角色、风格、场景高度一致性,让零动画经验者也能高效产出专业级叙事内容。广泛适用于独立创作者、动画工作室、教育机构及企业营销,助您轻松实现创意落地与商业化。
- 3797次使用
-
- JavaScript函数定义及示例详解
- 2025-05-11 502浏览
-
- 优化用户界面体验的秘密武器:CSS开发项目经验大揭秘
- 2023-11-03 501浏览
-
- 使用微信小程序实现图片轮播特效
- 2023-11-21 501浏览
-
- 解析sessionStorage的存储能力与限制
- 2024-01-11 501浏览
-
- 探索冒泡活动对于团队合作的推动力
- 2024-01-13 501浏览

