React 入门笔记
前言
国庆值班把假期拆了个稀碎, 正好不用去看人潮人海, 趁机会赶个晚集入门一下都火这么久的 React 前端技术. 话说其实 n 年前也了解过一丢丢来着, 当时看到一上来就用 JS 写 DOM 的套路直接就给吓退了, 扭头还去看 Vue 了🤣, 现在从市场份额 社区活度来看, 确实 React 还是占有率更高 (数据来源) 加上单位现在也都在推 CloudScape 做项目, 有必要再试一试了.
本次入门主要围绕 React 前端开发的环境准备和基本功能实现, 后端用 https://reqres.in/api/users?page=2 提供的 Mock 数据, 以后有空再尝尝 FastAPI (挖个坑先). Mock 数据长这样:
{"page": 2,"per_page": 6,"total": 12,"total_pages": 2,"data": [{"id": 7,"email": "michael.lawson@reqres.in","first_name": "Michael","last_name": "Lawson","avatar": "https://reqres.in/img/faces/7-image.jpg"},// 省略更多其他相同结构数据],"support": {"url": "https://reqres.in/#support-heading","text": "To keep ReqRes free, contributions towards server costs are appreciated!"}
}
计划使用这些数据制作一个通信录页面, 包含每个人物的基本信息, 以卡片形式排列展示.
环境准备
- Windows 11 + VScode
- 安装 nodejs https://nodejs.org/
# 检查 nodejs 版本
node -v
v20.8.0# 修改镜像源
npm config set registry https://registry.npmmirror.com
使用 Vite 脚手架创建项目
# 创建文件夹
mkdir my-react; cd my-react# 创建项目
npm create vite# 完成向导, 使用 React + TypeScript 组合
Need to install the following packages:
create-vite@4.4.1
Ok to proceed? (y)
√ Project name: ... frontend
√ Select a framework: » React
√ Select a variant: » TypeScriptScaffolding project in C:\Users\lpwm\Desktop\react-study\my-react\frontend...Done. Now run:cd frontendnpm installnpm run dev# 安装基础的 React 依赖
cd frontend; npm install# 使用 VScode 打开项目
code .
VScode 插件配置
安装以下插件可以使 Coding 的快乐(效率)加倍
- ES7 React/Redux/Styled-components snippets 常用代码片段
- Prettier - Code formatter 格式化
- vscode-icons 扩展图标(好看)
快捷键 Ctrl
+ ,
打开 VScode 设置, 搜索 “format on save”, 勾选上 Editor: Format On Save
; 搜索 “default formatter” , Editor: Default Formatter
选择 Prettier - Code formatter
配置完的项目 Folder 长这个样子:
通过 Vite 脚手架创建的项目中乍一看好多文件, 其实大多数都不需要动, 主要 focus 在 src
里面就中.
安装 UI 依赖
React 其实并不会包含和 UI 相关的 Component / Style, 这部分还是需要使用其他的前端 UI 框架, 这里使用老朋友 Bootstrap 适配 React 的版本 React Bootstrap, 在 VScode 中通过快捷键 Ctrl
+ Shift
+ `
打开 PowerShell 终端:
npm install react-bootstrap bootstrap
安装完成后可以检查 package.json
可以看到内容已经自动更新, 非高端玩家其实项目中的大多数配置文件都不需要手动修改的.
"dependencies": {"bootstrap": "^5.3.2","react": "^18.2.0","react-bootstrap": "^2.9.0","react-dom": "^18.2.0"
},
Coding
Vite 创建的项目中包含了一个演示的页面, 对于新手来说, 看起来会比较混乱, 先删除 src 中的 App.css, index.css 这两个自定义的样式文件.
修改 src/main.tsx
删除 import './index.css'
这行相关的引用.
修改 src/App.tsx
删除所有内容, 输入 tsrafce
按 TAB 键自动补全填充代码片段 (其实不用输入完就能联想出来了) 这里其实是调用前面装的插件 ES7 React/Redux/Styled-components snippets
Creates a React Arrow Function Component with ES7 module system and TypeScript interface (ES7 React/Redux/Styled-components snippets)
自动补全的 React Component 代码(真省事):
import React from 'react'interface Props {}const App = (props: Props) => {return (<div></div>)
}export default App
其实 JSX 也没有像之前想象的那么晦涩, 当成 XML 来对待就行了. 修改上面的代码, 删除没有用到的部分, 添加一个静态的 Bootstrap Navbar 和 Card. 在 return ()
中输入 <Container
就会出现自动联想, 按 TAB 键就可以自动补全相关的 import
代码, 就很欢快了有木有! 另外得益于之前在 VScode 中设置的 Editor: Format On Save
, 保存文件时会自动通过 Prettier 进行格式化.
参考 React Bootstrap 文档 完成页面设计.
import { Card, Col, Container, Navbar, Row } from "react-bootstrap";
// 别忘了添加 Bootstrap CSS 文件引用
import "bootstrap/dist/css/bootstrap.min.css";const App = () => {return (<Container fluid><Row><Navbar expand="lg" className="bg-primary-subtle"><Container><Navbar.Brand>Contacts</Navbar.Brand></Container></Navbar></Row><Container className="p-3">{/* Container 加上 padding 类 */}<Row md="4">{/* 在 Row 上定义 Grid Column (每行最多 4 列) */}<Col><Card className="m-2">{/* 加上 margin 类 */}<Card.Img variant="top" src="holder.js/100px180"></Card.Img><Card.Body><Card.Title>Card Title</Card.Title><Card.Text>Some text in the card.</Card.Text></Card.Body></Card></Col></Row></Container></Container>);
};export default App;
在 Terminal 中启动开发服务器
npm run devVITE v4.4.9 ready in 200 ms➜ Local: http://localhost:5174/➜ Network: use --host to expose➜ press h to show help
浏览器访问 http://localhost:5174/
预览效果
多复制几个 Card 所在的 <Col></Col>
查看 Grid Column 效果:
静态页面已经没问题了, 接下来使用 https://reqres.in/api/users?page=2 模拟后端 API 返回的数据进行页面动态渲染, 修改后的 App.tsx
import { Card, Col, Container, Navbar, Row } from "react-bootstrap";
// 别忘了添加 Bootstrap CSS 文件引用
import "bootstrap/dist/css/bootstrap.min.css";
import { useEffect, useState } from "react";
import React from "react";// 使用 Context 管理组件内部的上下文内容
const AppContext = React.createContext({users: [],fetchUsers: () => {},
});const App = () => {// 模拟异步获取 API 数据const [users, setUsers] = useState([]);const fetchUsers = async () => {await fetch("https://reqres.in/api/users?page=2").then((response) => {return response.json();}).then((json_data) => {setUsers(json_data["data"]);});};useEffect(() => {fetchUsers();}, []);return (<AppContext.Provider value={{ users, fetchUsers }}><Container fluid><Row><Navbar expand="lg" className="bg-primary-subtle"><Container><Navbar.Brand>Contacts</Navbar.Brand></Container></Navbar></Row><Container className="p-3">{/* Container 加上 padding 类 */}<Row md="4">{/* 在 Row 上定义 Grid Column (每行最多 4 列) */}{users.map((user) => (<Col key={user["id"]}><Card className="m-2">{/* 加上 margin 类 */}<Card.Img variant="top" src={user["avatar"]}></Card.Img><Card.Body><Card.Title>{user["first_name"]}</Card.Title><Card.Text>Some text in the card.</Card.Text></Card.Body></Card></Col>))}</Row></Container></Container></AppContext.Provider>);
};export default App;
刷新浏览器查看效果:
由于图片的高度不一致, 导致显示的 Card 大小也不一样, 先通过自定义 inline 样式的方式解决, 修改 Card.Img
添加 style
属性
<Card.Imgvariant="top"src={user["avatar"]}style={{ height: "100px", objectFit: "cover" }}
></Card.Img>
刷新页面, 制式~
换种方式, 将自定义样式放到单独的文件中, 然后为 Card.Img
添加 className
属性. 创建文件 src/App.css
(就是开头删掉的那个🤣)
.card-avatar {height: 100px;object-fit: cover;
}
修改 App.tsx
, 在开头加入引用 import "./App.css";
, 并调整 Card.Img
<Card.Imgvariant="top"src={user["avatar"]}className="card-avatar"
></Card.Img>
再次刷新浏览器, 格式保持一致. 至此, 一个简单的 React 页面就开发完成了. 其实后面涉及到的 React.createContext
, useState
, useEffect
还属于一知半解, 也没好意思展开强行解释. 能先跑出来效果就打消了不少之前对 React 的恐惧了, 后面还是得花时间好好看一遍文档和基础学习.
项目部署
现在都是在本地通过 npm run dev
跑的开发测试环境, 生产部署的简单过程:
- Build, 会在项目文件夹中创建
dist
目录
npm run build
- 将
dist
目录中的文件部署到 Web Server, 以 WSL2 (Ubuntu 22.04) 中的 nginx 为例
# 先安装 nginx
sudo apt install nginx -y# 从 Windows 的资源管理器中
# 将 dist 文件夹复制到 WSL2 的 Home 文件夹: /home/lpwm/dist
# 修改 nginx 配置
sudo vim /etc/nginx/sites-enabled/default
nginx 配置文件简单示意:
server {listen 80;root /home/lpwm/dist;
}
启动 nginx 服务
sudo systemctl restart nginx
此时通过浏览器访问 http://localhost
返回 403 Forbidden
, 查看 /var/log/nginx/error.log
发现:
2023/10/01 01:09:59 [error] 1117#1117: *1 “/home/lpwm/dist/index.html” is forbidden (13: Permission denied), client: 127.0.0.1, server: , request: “GET / HTTP/1.1”, host: “localhost”
使用 sudo ps -ef |grep nginx
检查当前运行 nginx 的用户是 www-data
, 没有对 /home/lpwm/dist
文件夹的访问权限. 这个好说, 把 www-data
用户添加到我自己用户的 lpwm
组就行了呗
sudo usermod -aG lpwm www-data
sudo nginx -s reload
齐活儿~
本次入门就先到这里吧, 后面抽时间再细琢磨 React 里面的各种基础概念.
参考资料
React Tutorial for Beginners - Programming with Mosh
相关文章:

React 入门笔记
前言 国庆值班把假期拆了个稀碎, 正好不用去看人潮人海, 趁机会赶个晚集入门一下都火这么久的 React 前端技术. 话说其实 n 年前也了解过一丢丢来着, 当时看到一上来就用 JS 写 DOM 的套路直接就给吓退了, 扭头还去看 Vue 了🤣, 现在从市场份额 社区活度来看, 确实…...

Ubuntu MySQL
在安装前,首先看你之前是否安装过,如果安装过,但是没成功,就要先卸载。 一、卸载 1.查看安装 dpkg --list | grep mysql 有东西,就说明您之前安装过mysql。 2.卸载 先停掉server sudo systemctl stop mysql.servic…...

大数据软件系统开发框架
大数据处理框架是用于处理大规模数据集的软件工具和平台,它们可以帮助分析、存储和处理庞大的数据量。以下是一些常见的大数据处理框架,希望对大家有所帮助。北京木奇移动技术有限公司,专业的软件外包开发公司,欢迎交流合作。 1.A…...
rust变量
一 、变量定义 (一)语法格式 使用let关键字定义变量 let varname: type value; 如,let a: i32 78;也可以不显式指定类型 let varname value; 如,let a 78;一些例子 1.布尔 let t true; let f: bool false;2.整数 let a …...
蓝桥杯---第一讲 递归与递推
文章目录 前言Ⅰ. 递归实现指数型枚举0x00 算法思路0x00 代码书写0x00 思考总结 Ⅱ. 递归实现排列型枚举0x00 算法思路0x01代码书写0x02 思考总结 Ⅲ. 简单斐波那契0x00 算法思路0x01 代码书写 Ⅳ. 费解的开关0x00 算法思路0x01 代码书写 Ⅴ. 递归实现组合型枚举0x00 算法思路0…...

OpenCV 15(SIFT/SURF算法)
一、SIFT Harris和Shi-Tomasi角点检测算法,这两种算法具有旋转不变性,但不具有尺度不变性,以下图为例,在左侧小图中可以检测到角点,但是图像被放大后,在使用同样的窗口,就检测不到角点了。 尺度…...
前端二维码图片解析图片识别/网络图片解析成链接/图片网络链接转本地链接(Js/Vue/Jquery)
注:需要用到canvas/jsqr/jquery! 1、远程图片链接本地化 页面: <!-- 识别二维码用的 canvas--> <canvas class"canvas" ref"canvas" style"display: none"></canvas> 1.创建图片 get2: fu…...

模板中的依赖类型使用 --- typename
依赖类型,顾名思义就是依赖于模板参数的类型,在使用这种类型时,必须使用 typename,否则编译器是无法知道是在使用类型,还是类的成员(因为类的静态成员的使用方法也是T::xxx,这跟某个类中的类型的…...

git 同时配置 gitee github
git 同时配置 gitee github 1、 删除C:\Users\dell\.ssh目录。 在任意目录右击——》Git Bash Here,打开Git Bash窗口,下方命令在Git Bash窗口输入。 2、添加git全局范围的用户名和邮箱 git config --global user.email "609612189qq.com" …...
2023.10.8 面试
面试工作1年的程序员 看到生涩才入职场不久的面试者,为人也相对诚恳的模样,我对此是很欣赏的态度。 因为完全看到了自己毕业1年时的场景。 简历上写的事情,讨论起来,描述不清楚,为此感到遗憾,因我本人也会…...
【前端】js实现队列功能 先进后出 先进先出 等
也可以定义一个定时器 不断的去取队列 执行任务 用一个flag定义队列正在执行中, 如果没有执行 则定时器不断的去调用队列,(因为会随时添加一个任务到队列中) 队列任务结束后 自动取下一个队列 也可以边加队列 边取 队列定义 function Queue() {//初始化队列(使用…...
07.数据持久化之文件操作
1. 文件操作 计算机的文件,就是存储在某种 长期储存设备 上的一段 数据 长期存储设备包括:硬盘、U 盘、移动硬盘、光盘… 文本文件和二进制文件 文本文件 可以使用 文本编辑软件 查看本质上还是二进制文件例如:python 的源程序 二进制文件…...

nginx开启https配置之后网页无法访问问题处理
背景说明 最近新购服务器部署nginx之后按照之前的方式部署前端项目并配置https之后访问页面显示:无法访问.新的服务器ECS系统和之前相同,nginx安装方式也相同,nginx配置方式也是相同.但是访问还是显示无法访问.下面简单记录一下问题处理过程. 处理过程 1.https访问之后无法访问…...

文本嵌入层
目录 1、文本嵌入层的作用 2、代码演示 3、构建Embeddings类来实现文本嵌入层 1、文本嵌入层的作用 无论是源文本嵌入层还是目标文本嵌入,都是为了将文本词汇中的数字表示转变为向量表示,希望在这样的高维空间中捕捉词汇之间的关系 2、代码演示 Emb…...

如何搭建自动化测试框架
关于测试框架的好处,比如快速回归提高测试效率,提高测试覆盖率等这里就不讨论了。这里主要讨论自动化框架包含哪些内容,以及如何去设计一个测试框架。 1. 什么是自动化测试框架? 它是由一个或多个自动化测试基础模块、自动化测试…...

抄写Linux源码(Day17:你的键盘是什么时候生效的?)
回忆我们需要做的事情: 为了支持 shell 程序的执行,我们需要提供: 1.缺页中断(不理解为什么要这个东西,只是闪客说需要,后边再说) 2.硬盘驱动、文件系统 (shell程序一开始是存放在磁盘里的,所以需要这两个东…...

在原生html中使用less
引入less <link rel"stylesheet/less" href"./lessDemo.less" /><script src"./js/less.min.js"></script> less.min.js文件下载地址:https://github.com/less/less.js 注意:less文件在前,js文件在后…...

【Qt】顶层窗口和普通窗口区别以及用法
区别 在Qt项目开发中,经常会用到窗体控件用于显示及数据操作和其他交互等。 但,窗体分为顶层窗口(Top-level Window)和普通窗口(Regular Window)。 他们之间是有区别的,包括在项目实际中的用法…...

qt开发从入门到实战2
以下是本人学习笔记 原视频:最新QT从入门到实战完整版|传智教育 qt开发从入门到实战1 练习示例 设计一个按钮,点击时弹出新窗口,再次点击时新窗口关闭 // exerciseQWidget* second_window new QWidget();QPushButton* btn3 new QPushBu…...

Android---字节码层面分析Class类文件
Java 提供了一种可以在所有平台上都能使用的一种中间代码---字节码文件(.class文件)。有了字节码,无论是那个平台只要安装了虚拟机都可以直接运行字节码文件。有了虚拟机,解除了 java 虚拟机与 java 代码之间的耦合。 Java 虚拟机当初被设计出来时就不单…...
后进先出(LIFO)详解
LIFO 是 Last In, First Out 的缩写,中文译为后进先出。这是一种数据结构的工作原则,类似于一摞盘子或一叠书本: 最后放进去的元素最先出来 -想象往筒状容器里放盘子: (1)你放进的最后一个盘子(…...
day52 ResNet18 CBAM
在深度学习的旅程中,我们不断探索如何提升模型的性能。今天,我将分享我在 ResNet18 模型中插入 CBAM(Convolutional Block Attention Module)模块,并采用分阶段微调策略的实践过程。通过这个过程,我不仅提升…...
Cesium1.95中高性能加载1500个点
一、基本方式: 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...

DAY 47
三、通道注意力 3.1 通道注意力的定义 # 新增:通道注意力模块(SE模块) class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...
django filter 统计数量 按属性去重
在Django中,如果你想要根据某个属性对查询集进行去重并统计数量,你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求: 方法1:使用annotate()和Count 假设你有一个模型Item,并且你想…...

对WWDC 2025 Keynote 内容的预测
借助我们以往对苹果公司发展路径的深入研究经验,以及大语言模型的分析能力,我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际,我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测,聊作存档。等到明…...
在Ubuntu中设置开机自动运行(sudo)指令的指南
在Ubuntu系统中,有时需要在系统启动时自动执行某些命令,特别是需要 sudo权限的指令。为了实现这一功能,可以使用多种方法,包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法,并提供…...

基于Docker Compose部署Java微服务项目
一. 创建根项目 根项目(父项目)主要用于依赖管理 一些需要注意的点: 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件,否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...
vue3 定时器-定义全局方法 vue+ts
1.创建ts文件 路径:src/utils/timer.ts 完整代码: import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...

现代密码学 | 椭圆曲线密码学—附py代码
Elliptic Curve Cryptography 椭圆曲线密码学(ECC)是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础,例如椭圆曲线数字签…...