黑马React18: 基础Part 1
黑马React: 基础1
Date: November 15, 2023
Sum: React介绍、JSX、事件绑定、组件、useState、B站评论
React介绍
概念: React由Meta公司研发,是一个用于 构建Web和原生交互界面的库

优势: 1-组件化的开发方式 2-优秀的性能 3-丰富的生态 4-跨平台开发
开发环境搭建
使用create-react-app快速搭建开发环境
create-react-app是一个快速 创建React开发环境的工具,底层由Webpack构建,封装了配置细节,开箱即用
执行命令:
npx create-react-app react-basic
- npx Node.js工具命令,查找并执行后续的包命令
- create-react-app 核心包(固定写法),用于创建React项目
- react-basic React项目的名称(可以自定义)
之后切入到文件夹下, 使用 npm start启动项目

创建React项目的更多方式: https://zh-hans.react.dev/learn/start-a-new-react-project
工作方式:

理解:
| index.js | 项目入口 |
|---|---|
| App.js | 项目的根组件 |
| index.html | html文件 |
项目的根组件以React组件的方式渲染到index.html中
-
Code:
index.js 简化后的内容
// 项目的入口 从这里开始// React必要的两个核心包 import React from 'react'; import ReactDOM from 'react-dom/client';// 导入项目的根组件 import App from './App';// 把App根组件渲染到id为root的dom节点上 const root = ReactDOM.createRoot(document.getElementById('root')); root.render(<App /> );
JSX基础-概念和本质
什么是JSX
**概念:**JSX是JavaScript和XML(HTML)的缩写,表示在JS代码中编写HTML模版结构,它是React中编写UI模版的方式

优势:
- HTML的声明式模版写法 2. JS的可编程能力
JSX的本质
JSX并不是标准的JS语法,它是JS的语法扩展,浏览器本身不能识别,需要通过解析工具做解析之后才能在浏览器中运行

JSX基础-高频场景
JSX中使用JS表达式
在JSX中可以通过 大括号语法{} 识别 JavaScript中的表达式,比如常见的变量、函数调用、方法调用等等
- 使用引号传递字符串
- 使用JavaScript变量
- 函数调用和方法调用
- 使用JavaScript对象
注意:if语句、switch语句、变量声明属于语句,不是表达式,不能出现在{}中
案例:
-
Code:
// 项目的根组件 // App -> index.js -> public/index.html(root)const count = 100function getName() {return 'jack' }function App() {return (<div className="App">this is App{/* 使用引号传递字符串 */}{'this is message'}{/* 识别js变量 */}{count}{/* 函数调用 */}{getName()}{/* 方法调用 */}{new Date().getDate()}{/* 使用js对象 */}<div style={{ color: 'red'}}>this is div</div></div>) }export default App
效果:

JSX中实现列表渲染
**语法:**在JSX中可以使用原生JS中的map方法遍历渲染列表

案例:
const list = [{ id: 1001, name: 'Vue'},{ id: 1002, name: 'React'},{ id: 1003, name: 'Angular'}
]function App() {return (<div className="App">this is App{/* 渲染列表 */}<ul>{/* { list.map(item => <li>Vue</li>) } */}{ list.map(item => <li key={item.id}>{ item.name }</li>) }</ul></div>)
}export default App
效果:

要点:
1-key值绑定
作用: 提升性能
方式: 每一项要加上一个独一无二的key值
JSX中实现条件渲染

**语法:**在React中,可以通过逻辑与运算符&&、三元表达式(?:)实现基础的条件渲染
案例:
const isLogin = truefunction App() {return (<div className="App">{/* 逻辑与 && */}{ isLogin && <span>this is span</span>}{/* 三目运算符 */}{ isLogin ? <span>this is span</span> : <div>this is div</div>}{/* 逻辑或 || */}{ isLogin || <span>this is span</span>}</div>)
}export default App
效果:
this is spanthis is span
JSX中实现复杂条件渲染

需求:列表中需要根据文章状态适配三种情况,单图,三图,和无图三种模式
解决方案:自定义函数 + if判断语句
案例:
// 定义文章类型
const articleType = 3 // 0 1 3// 定义核心函数(根据文章类型返回不同的JSX模版)function getArticleTem () {if (articleType === 0) {return <div>我是无图文章</div>} else if (articleType === 1) {return <div>我是单图模式</div>} else {return <div>我是三图模式</div>}
}function App () {return (<div className="App">{/* 调用函数渲染不同的模版 */}{getArticleTem()}</div>)
}export default App
效果:
我是三图模式
React中的事件绑定
React 基础事件绑定
**语法:**on + 事件名称 = { 事件处理程序 },整体上遵循驼峰命名法
Code:
function App() {const handleClick = () => {console.log('button被点击了');}return (<div className="App"><button onClick={handleClick}>Click</button></div>)
}export default App
Res:

使用事件对象参数
语法:在事件回调函数中设置形参e
Code:
function App() {const handleClick = (e) => {console.log('button被点击了', e);}return (<div className="App"><button onClick={handleClick}>Click</button></div>)
}export default App
Res:

传递自定义参数
语法:事件绑定的位置改成箭头函数的写法,在执行clickHandler实际处理业务函数的时候传递实参
Code:
function App() {const handleClick = (name) => {console.log('button被点击了', name);}return (<div className="App"><button onClick={() => handleClick('jack')}>Click</button></div>)
}export default App
Res:

注意:不能直接写函数调用,这里事件绑定需要一个函数引用
同时传递事件对象和自定义参数
语法:在事件绑定的位置传递事件实参e和自定义参数,clickHandler中声明形参,注意顺序对应
Code:
function App() {const handleClick = (name, e) => {console.log('button被点击了', name, e);}return (<div className="App"><button onClick={(e) => handleClick('jack', e)}>Click</button></div>)
}export default App
Res:

React中的组件
组件是什么
概念:一个组件就是用户界面的一部分,它可以有自己的逻辑和外观,组件之间可以互相嵌套,也可以复用多次

组件化开发可以让开发者像搭积木一样构建一个完整的庞大的应用
React组件
在React中,一个组件就是首字母大写的函数,内部存放了组件的逻辑和视图UI, 渲染组件只需要把组件当成标签书写即可
Code:
function Button() {return <button>click me!</button>
}function App() {return (<div className="App">{/* 自闭合 */}<Button />{/* 成对标签 */}<Button></Button></div>)
}export default App
Res:

useState
useState基础使用
概念:
useState 是一个 React Hook(函数),它允许我们向组件添加一个状态变量, 从而控制影响组件的渲染结果

本质:和普通变量不同的是,状态变量一旦发生变化组件的视图UI也会跟着变化(数据驱动视图)
const [count, setCount] = useState(0)
1- useState是一个函数, 返回值是一个数组
2-数组中的第一个参数是状态变量, 第二个参数是set函数用来修改状态变量
3-useState的参数将作为count的初始值
Case:
func: 点击按钮, 数值不断增加
Code:
import { useState } from "react"function App() {// 1. 调用 useState 添加一个状态变量// count 状态变量// setCount 修改状态变量的方法const [count, setCount] = useState(0)// 2. 点击事件const handleClick = () => {setCount(count + 1)}return (<div className="App"><button onClick={ () => handleClick()}>Add-{count}</button></div>)
}export default App
Res:

修改状态的规则
状态不可变
在React中,状态被认为是只读的,我们应该始终替换它而不是修改它,直接修改状态不能引发视图更新


Case:
Code:
import { useState } from "react"function App() {// 1. 调用 useState 添加一个状态变量// count 状态变量// setCount 修改状态变量的方法const [count, setCount] = useState(0)// 2. 点击事件const handleClick = () => {setCount(count + 1)}return (<div className="App"><button onClick={ () => handleClick()}>Add-{count}</button></div>)
}export default App
修改对象状态
规则:对于对象类型的状态变量,应该始终传给set方法一个全新的对象来进行修改
直接修改原对象,不引发视图变化

调用set传入新对象用于修改

理解: 这里先用展开运算符做个拷贝, 然后再用后面重复属性进行替换即可.
Case:
func: 点击按变换名字
Code:
import { useState } from "react"function App() {const [form, setForm] = useState({ name: 'jack' })const handleClick = () => {setForm({...form,name: 'rose'})}return (<div className="App"><button onClick={ () => handleClick()}>Add-{form.name}</button></div>)
}export default App
Res:

复习知识点:
1-…展开匀速符: 深浅拷贝问题
展开运算符使用的对象如果只是针对简单的一级基础数据,就是深拷贝;
展开运算符使用的对象内容包含二级或更多的复杂的数据,那就是浅拷贝;
组件的样式处理
组件基础样式方案
React组件基础的样式控制有俩种方式
- 行内样式(不推荐)

- class类名控制

Case:
Code:
index.js
import './css/index.css'const style = {color: 'red',fontSize: '20px'
}function App() {return (<div className="App">{/* 行内样式控制 */}<div style={{ color: 'red'}}>this is span</div>{/* 内部样式控制 */}<div style={style}>this is span</div>{/* 外部样式控制 */}<span className='outer'>this is span</span></div>)
}export default App
index.css
.outer {background-color: blue;
}

案例:B站评论
效果展示:

- 渲染评论列表
- 删除评论实现
- 渲染导航Tab和高亮实现
- 评论列表排序功能实现
渲染评论列表
核心思路:
- 使用useState维护评论列表
- 使用map方法对列表数据进行遍历渲染(别忘了加key)
key Code:
const [commentList, setCommentList] = useState([])
<div className="reply-list">{/* 评论项 */}{commentList.map(item => <Item key={item.id} item={item} onDel={handleDel} />)}</div>
</div>
实现评论删除
需求:
- 只有自己的评论才显示删除按钮
- 点击删除按钮,删除当前评论,列表中不再显示
核心思路
- 删除显示 - 条件渲染 2. 删除功能 - 拿到当前项id以id为条件对评论列表做filter过滤
handleDel实现列表过滤
// 删除功能
const handleDel = (id) => {console.log(id)// 对commentList做过滤处理setCommentList(commentList.filter(item => item.rpid !== id))
}
匹配删除 onDel
{/* 条件:user.id === item.user.id */}
{user.uid === item.user.uid &&
<span className="delete-btn" onClick={() => onDel(item.rpid)}>删除
</span>}
渲染Tab+点击高亮实现
需求:点击哪个tab项,哪个做高亮处理
核心思路:
点击谁就把谁的type(独一无二的标识)记录下来,然后和遍历时的每一项的type做匹配,谁匹配到就设置负责高亮的类名
Code:
// 导航 Tab 数组
const tabs = [{ type: 'hot', text: '最热' },{ type: 'time', text: '最新' },
]...// tab切换功能
// 1. 点击谁就把谁的type记录下来
// 2. 通过记录的type和每一项遍历时的type做匹配 控制激活类名的显示
const [type, setType] = useState('hot')
const handleTabChange = (type) => {console.log(type)setType(type)// 基于列表的排序if (type === 'hot') {// 根据点赞数量排序 // lodashsetCommentList(_.orderBy(commentList, 'like', 'desc'))} else {// 根据创建时间排序setCommentList(_.orderBy(commentList, 'ctime', 'desc'))}
}...<li className="nav-sort">{/* 高亮类名: active */}{tabs.map(item =><spankey={item.type}onClick={() => handleTabChange(item.type)}className={classNames('nav-item', { active: type === item.type })}>{item.text}</span>)}
</li>
排序功能实现

需求:
点击最新,评论列表按照创建时间倒序排列(新的在前),点击最热按照点赞数排序(多的在前)
**核心思路:**把评论列表状态数据进行不同的排序处理,当成新值传给set函数重新渲染视图UI
Code:
method: 采用 lodash 来进行排序处理
// 基于列表的排序
if (type === 'hot') {// 根据点赞数量排序 // lodashsetCommentList(_.orderBy(commentList, 'like', 'desc'))
} else {// 根据创建时间排序setCommentList(_.orderBy(commentList, 'ctime', 'desc'))
}
classnames优化类名控制
classnames是一个简单的JS库,可以非常方便的通过条件动态控制class类名的显示

现在的问题:字符串的拼接方式不够直观,也容易出错

理解: classNames 是一个可以执行的方法, key用来控制类型, value用来控制条件
参考:
React:
React入门到实战导学课程_哔哩哔哩_bilibili
相关文章:
黑马React18: 基础Part 1
黑马React: 基础1 Date: November 15, 2023 Sum: React介绍、JSX、事件绑定、组件、useState、B站评论 React介绍 概念: React由Meta公司研发,是一个用于 构建Web和原生交互界面的库 优势: 1-组件化的开发方式 2-优秀的性能 3-丰富的生态 4-跨平台开发 开发环境搭…...
windows Oracle Database 19c 卸载教程
目录 打开任务管理器 停止数据库服务 Universal Installer 卸载Oracle数据库程序 使用Oracle Installer卸载 删除注册表项 重新启动系统 打开任务管理器 ctrlShiftEsc可以快速打开任务管理器,找到oracle所有服务然后停止。 停止数据库服务 在开始卸载之前&a…...
动态规划解决leetcode上的两道回文问题(针对思路)
本期主讲的是使用动态规划去解决两道回文问题,分别是 647. 回文子串 - 力扣(LeetCode) 516. 最长回文子序列 - 力扣(LeetCode) 而不是leetcode5.最长回文子串,虽然这道题也是回文问题,也可以…...
使用人工智能自动测试 Flutter 应用程序
移动应用程序开发的增长速度比以往任何时候都快。几乎每个企业都需要移动应用程序来保持市场竞争力。由于像 React Native 这样的跨平台移动应用程序开发框架允许公司使用单一源代码和单一编程语言构建 iOS 和 Android 应用程序, Flutter是 Google 支持的另一个热门…...
四、程序员指南:数据平面开发套件
REORDER LIBRARY 重排序库提供了根据其序列号对mbuf进行重排序的机制。 16.1 操作 重排序库本质上是一个对mbuf进行重新排序的缓冲区。用户将乱序的mbuf插入重排序缓冲区,并从中提取顺序正确的mbuf。 在任何给定时刻,重排序缓冲区包含其序列号位于序列…...
Go 之 captcha 生成图像验证码
目前 chptcha 好像只可以生成纯数字的图像验证码,不过对于普通简单应用来说也足够了。captcha默认将store封装到内部,未提供对外操作的接口,因此使用自己显式生成的store,可以通过store自定义要生成的验证码。 package mainimpor…...
【Java从入门到大牛】多线程
🔥 本文由 程序喵正在路上 原创,CSDN首发! 💖 系列专栏:Java从入门到大牛 🌠 首发时间:2023年11月18日 🦋 欢迎关注🖱点赞👍收藏🌟留言Ǵ…...
UE5 C++报错:is not currently enabled for Live Coding
解决办法: 再次打开项目,以此法打开:...
mysql服务器数据同步
在Linux和Windows之间实现MySQL服务器数据的同步。下面是一些常见的方法和工具: 复制(Replication):MySQL复制是一种常见的数据同步技术,可用于将一个MySQL服务器的数据复制到其他服务器。您可以设置主服务器ÿ…...
Docker Golang 开发环境搭建指南
Docker Golang 开发环境搭建指南 概述 在 Golang 开发中,搭建合适的开发环境是非常重要的。然而,由于 Golang 的跨平台特性,不同操作系统之间的配置差异可能会导致环境搭建过程变得复杂。为了简化这个过程并保持开发环境的一致性࿰…...
MFC保存窗口客户区为图片
首先的窗口输出一些内容; 菜单单击函数代码; void CgetmypicView::OnTestGetmypic() {// TODO: 在此添加命令处理程序代码HWND hwnd this->GetSafeHwnd();HDC hDC ::GetWindowDC(hwnd);//获取DC RECT rect;::GetClientRect(hwnd, &rect)…...
JAVA安全之Shrio550-721漏洞原理及复现
前言 关于shrio漏洞,网上有很多博文讲解,这些博文对漏洞的解释似乎有一套约定俗成的说辞,让人云里来云里去,都没有对漏洞产生的原因深入地去探究..... 本文从现象到本质,旨在解释清楚Shrio漏洞是怎么回事!…...
有Mac或无Mac电脑通用的获取安卓公钥的方案
从2023年9月开始,所有上架应用市场的app都需要进行APP备案。 其中后端服务器在阿里云的可以在阿里云备案,后端服务器在腾讯云的可以在腾讯云备案。但无论你是在什么云厂商里做备案,无一例外的是,无论是上架安卓应用还是上架IOS应…...
电池故障估计:Realistic fault detection of li-ion battery via dynamical deep learning
昇科能源、清华大学欧阳明高院士团队等的最新研究成果《动态深度学习实现锂离子电池异常检测》,用已经处理的整车充电段数据,分析车辆当前或近期是否存在故障。 思想步骤: 用正常电池的充电片段数据构造训练集,用如下的方式构造…...
微服务和Spring Cloud Alibaba介绍
1、微服务介绍 1.1 系统架构演变 随着互联网的发展,网站应用的规模也在不断的扩大,进而导致系统架构也在不断的进行变化。从互联网早起到现在,系统架构大体经历了下面几个过程: 单体应用架构 —> 垂直应用架构 —> 分布 式架构—>…...
【js】 lodash命名转换和封装
▒ 目录 ▒ 🛫 导读需求开发环境 1️⃣ lodash转换函数h3与underscore比较 2️⃣ 实战:对象属性名转换函数封装单元测试 🛬 文章小结📖 参考资料 🛫 导读 需求 爬虫中经常出现各种类型的命名,往往一个对象…...
RK3568驱动指南|第七篇 设备树-第67章 of操作函数实验:获取属性
瑞芯微RK3568芯片是一款定位中高端的通用型SOC,采用22nm制程工艺,搭载一颗四核Cortex-A55处理器和Mali G52 2EE 图形处理器。RK3568 支持4K 解码和 1080P 编码,支持SATA/PCIE/USB3.0 外围接口。RK3568内置独立NPU,可用于轻量级人工…...
vue3安装vue-router
环境 node 18.14.2 yarn 1.22.19 windows 11 vite快速创建vue项目 参考 安装vue-touter 官网 yarn add vue-router4src下新建router文件夹,该文件夹下新建index.ts // router/index.ts 文件 import { createRouter, createWebHashHistory, RouterOptions, Ro…...
〖大前端 - 基础入门三大核心之JS篇㊱〗- JavaScript 的DOM节点操作
说明:该文属于 大前端全栈架构白宝书专栏,目前阶段免费,如需要项目实战或者是体系化资源,文末名片加V!作者:不渴望力量的哈士奇(哈哥),十余年工作经验, 从事过全栈研发、产品经理等工作…...
【计算机基础】优雅的PPT就应该这样设计
📢:如果你也对机器人、人工智能感兴趣,看来我们志同道合✨ 📢:不妨浏览一下我的博客主页【https://blog.csdn.net/weixin_51244852】 📢:文章若有幸对你有帮助,可点赞 👍…...
XML Group端口详解
在XML数据映射过程中,经常需要对数据进行分组聚合操作。例如,当处理包含多个物料明细的XML文件时,可能需要将相同物料号的明细归为一组,或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码,增加了开…...
龙虎榜——20250610
上证指数放量收阴线,个股多数下跌,盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型,指数短线有调整的需求,大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的:御银股份、雄帝科技 驱动…...
【JavaEE】-- HTTP
1. HTTP是什么? HTTP(全称为"超文本传输协议")是一种应用非常广泛的应用层协议,HTTP是基于TCP协议的一种应用层协议。 应用层协议:是计算机网络协议栈中最高层的协议,它定义了运行在不同主机上…...
【力扣数据库知识手册笔记】索引
索引 索引的优缺点 优点1. 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度(创建索引的主要原因)。3. 可以加速表和表之间的连接,实现数据的参考完整性。4. 可以在查询过程中,…...
JVM垃圾回收机制全解析
Java虚拟机(JVM)中的垃圾收集器(Garbage Collector,简称GC)是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象,从而释放内存空间,避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...
[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...
c#开发AI模型对话
AI模型 前面已经介绍了一般AI模型本地部署,直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型,但是目前国内可能使用不多,至少实践例子很少看见。开发训练模型就不介绍了&am…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
dify打造数据可视化图表
一、概述 在日常工作和学习中,我们经常需要和数据打交道。无论是分析报告、项目展示,还是简单的数据洞察,一个清晰直观的图表,往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server,由蚂蚁集团 AntV 团队…...
Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信
文章目录 Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket(服务端和客户端都要)2. 绑定本地地址和端口&#x…...
