当前位置: 首页 > news >正文

react中JSX基础与useState的基本使用 + 评论显示删除需求案例

参考视频:https://www.bilibili.com/video/BV1ZB4y1Z7o8/?p=3&spm_id_from=pageDriver&vd_source=5c584bd3b474d579d0bbbffdf0437c70

如果没有安装create-react-app需要先全局安装

命令:npm i -g create-react-app

1.快速搭建开发环境

create-react-app是一个快速 创建react开发环境的工具,底层由webpack构建,封装了配置细节,开箱即用
执行命令:

npx create-react-app react-basic
  1. npx Node.js工具命令,查找并执行后续的包命令
  2. create-react-app 核心包(固定写法),用于创建react项目
  3. react-basic React项目的名称(可以自定义)
  4. 创建React项目的更多方式:https://zh-hans.react.dev/learn/start-a-new-react-project

2.项目文件

src/index.js ==> 入口文件
src/App.js ==>导入项目的根组件

3.JSX基础:概念和本质

  • 概念:
    JSX是Javascript和XML(HTML)的缩写,表示在JS代码中编写HTML模板结构,它是React中编写UI模板的方式
    优势:
  1. HTML的声明式模板写法
  2. JS的可编程能力
  • 本质:
    JSX并不是标准的JS语法,它是JS的语法扩展,浏览器本身不能识别,需要通过解析工具做解析之后才能在浏览器中运行。 (babel解析工具)
    babel网址:babeljs.io , 可以在左边输入js代码看右边编译在浏览器运行的代码,需要把react勾上才能解析JSX
    在这里插入图片描述
  • 高频场景:
  1. JSX中使用JS表达式:在JSX中可以使用大括号语法{}识别Javascript中的表达式,比如常见的变量、函数调用、方法调用等等。
    1.使用引号传递字符串 2.使用Javascript变量 3.函数调用和方法调用 4.使用Javascript对象
function getName() {return 'jack'
}
function Contuer() {const count = 100;return(<div>{/* 1.使用引号传递字符串, 字符串识别 */}{ 'this is message' }{/* 2.使用Javascript变量, 识别js变量 */}{ count }{/* 3.函数调用和方法调用 */}{ getName() } {/* 调用函数显示的是函数的返回值 */}{ new Date().getDate() } {/* 方法调用 */}{/* 4.使用Javascript对象, {}外层是识别对象的 */}<div style={{color: 'red'}}>this is div</div></div>)
}

注意:if语句、switch语句、变量声明属于语句,不是表达式,不能出现在{}中

4.JSX基础-实现列表渲染

在这里插入图片描述
map循环哪个结构直接return结构,通过map渲染需要绑定独一无二的key 字符串或者number,key的作用:React框架内部使用 提升更新性能的

5.JSX基础-实现条件渲染

在这里插入图片描述
语法:在React中,可以通过逻辑与运算符&&、三元表达式(?:)实现基础的条件渲染

{flag && <span>this is span</span>} // 判断一种情况,如果flag为true,span就显示,否则span不显示
{loading ? <span>loading...</span> : <span>加载完成</span>} // 两种情况(多个),loading为true就显示loading...,否则显示加载完成

6.JSX基础-复杂条件渲染

在这里插入图片描述

需求:列表中需要根据文章状态适配三种情况,单图、三图和无图三种模式
解决方案:自定义函数 + if 判断语句

const articleType = 3 // 0 1 3三种模式
function getArticleTem() {// 可以用switch做if (articleType === 0) {return <div>无图</div>} else if (articleType === 1) {return <div>一图</div>} else {return <div>三图</div>}
}
function Couter() {return(<div>{ getArticleTem() } {/* 调用函数渲染不同的模板 */}</div>)
}

8.React中的时间绑定

语法: on + 事件名称 = { 事件处理程序 }, 整体上遵循驼峰命名法
在这里插入图片描述

  • 使用事件对象参数
    在这里插入图片描述
  • 传递自定义参数
    在这里插入图片描述
  • 同时传递事件对象和自定义参数
    在这里插入图片描述

9.React组件基础使用

组件是什么?
概念:一个组件就是用户界面的一部分,它可以有自己的逻辑和外观,组件之间可以互相嵌套,也可以复用多次
在这里插入图片描述
组件化开发可以让开发者像搭积木一样构建一个完整的庞大的应用
在React中,一个组件就是首字母大写的函数(规定好的),内部存放了组建的逻辑和视图UI,渲染组件只需要把组件当成标签书写即可
在这里插入图片描述
在这里插入图片描述

function Button(){return <button>click me</button>
}
不一定非要function Button(){},  const Button = () => {}也是可以的,只要是首字母大写的函数就是组件
const Button = () => {return <button>click me</button>
}

10.useState基础使用

useState是一个React Hook(函数),它允许我们向组件添加一个状态变量,从而控制影响组件的渲染结果
本质:和普通JS变量不同的是,状态变量一旦发生变化组建的视图UI也会跟着变化(数据驱动视图)
在这里插入图片描述

  • useState修改状态的规则
    在这里插入图片描述
  • 修改对象状态
    在这里插入图片描述

11.React组件基础样式控制

  • 组件基础样式方案
    在这里插入图片描述
    使用style={{fontSize: '20px'}时,如果样式有带-的要改为驼峰写法}。使用class时<span className="class-name">span...</span>class要改为className

12.评论案例

在这里插入图片描述

12.1 列表渲染

思路:

  1. 使用useState维护评论列表
  2. 使用map方法对列表数据进行遍历渲染(别忘了加key)

-------------------------------------思考:为什么要用useState来维护评论列表?-----------------------------------
因为函数组件没有生命周期,执行完毕就结束了,即使值改变了,视图也不会更新。而用useState保存的数据改变之后会更新视图如图所示:
在这里插入图片描述
当点击事件发生,console.log(‘执行了’)也只会打印刚加载的一次,数据已经加上去了,但是视图还是两项没有更新
在这里插入图片描述
--------------------------------------------------思考结束:分割线--------------------------------------------

// 项目的根组件,组件从这往下分散
// App -> 引入到index.js -> 被里面的代码渲染到 public/index.html(root)import { useState } from 'react';
const list = [{name: 'jack',content: '这是评论回复111',time: '2023-6-10',likeNum: 100,uid: '1'},{name: 'rose',content: '这是评论回复222',time: '2023-6-11',likeNum: 230,uid: '2'}
]
const user = {uid: '3002017',avatar: '',uname: '张三'
}// 渲染评论列表
// 1.使用useState维护list
function App() {const [commentList, setCommentList] = useState(list);return (<div className="App"><span>评论{commentList.length}</span> <button>最新</button>|<button>最热</button><div>{user.uname}<input /><button>发布</button></div><div>{commentList.map(item => {return (<div key={item.uid}><div>{item.name}</div><div>{item.content}</div><div><span>{item.time}</span><span>点赞数:{item.likeNum}</span><button>删除</button></div></div>)})}</div></div>);
}export default App;
  • 实现评论删除
    做两件事情:删除按钮判断当前项里的uid是否等于用户uid,如果相等则显示删除按钮,如果不等不显示删除按钮
    给删除按钮绑定点击事件,当点击删除按钮时传入当前项的uid,在事件中用数组过滤掉当前项
const handleDelete = (uid) => {setCommentList(commentList.fliter(item => item.uid !== uid));
}

12.2 渲染tab + 点击高亮实现

在这里插入图片描述
map渲染tab数组之后,绑定一个点击事件,传当前项的type,判断当前项的type是否等于一个记录的值,如果相等就让字体颜色高亮

const [tabType, setTabType] = useState(0);
const handleTab = (type) => {setTabType(type);
}return内:
{tab.map(item => <span key={item.type} style={{color: tabType === item.type? 'blue' : '#aaa'}} onClick="() => handleTab(type)">{item.value}</span>)}

12.3 排序功能实现

在这里插入图片描述

  1. 排序可以使用lodash,会生成一份全新的数据,不会更改老数据
    lodash官网:lodash.com / lodash.com/docs/
    在这里插入图片描述
    在这里插入图片描述
    如果需要进来就按第一个高亮的排序,就在初始加载数据那排序
    在这里插入图片描述
  2. 用array.sort()给数组排序
// 项目的根组件,组件从这往下分散
// App -> 引入到index.js -> 被里面的代码渲染到 public/index.html(root)import { useState } from 'react';
const list = [{name: 'jack',content: '这是评论回复111',time: '2023-6-10',likeNum: 100,uid: '1'},{name: 'rose',content: '这是评论回复222',time: '2023-6-11',likeNum: 230,uid: '2'},{name: '张三',content: '这是评论回复333',time: '2023-6-9',likeNum: 320,uid: '3'},
]
const tab = [{type: 'time',value: '最新'},{type: 'likeNum',value: '最热'}
]
const user = {uid: '3',avatar: '',uname: '张三'
}// 渲染评论列表
// 1.使用useState维护list
function App() {const [commentList, setCommentList] = useState(list);const [tabType, setTabType] = useState();const handleDelete = (uid) => {// 拿到需要删除uid的评论setCommentList(commentList.filter(item => item.uid !== uid ));}const hanldeTab = (type) => {// 拿到点击的type值setTabType(type);// 基于列表的排序if (type === 'time') {// 根据时间排序setCommentList(commentList.sort((a,b) => {return new Date(b.time).getTime() - new Date(a.time).getTime();}))} else {// 根据点赞数排序setCommentList(commentList.sort((a,b) => {return b.likeNum - a.likeNum;}))}}return (<div className="App"><span>评论{commentList.length}</span>{tab.map(item => <span key={item.type} style={{padding: '9px',color: tabType === item.type ? 'blue' : '#aaa', cursor: 'pointer'}}onClick={() => hanldeTab(item.type)}>{item.value}</span>)}<div>{user.uname}<input /><button>发布</button></div><div>{commentList.map(item => {return (<div key={item.uid}><div>{item.name}</div><div>{item.content}</div><div><span>{item.time}</span><span>点赞数:{item.likeNum}</span>{ item.uid === user.uid && <button onClick={() => handleDelete(item.uid)}>删除</button> }</div></div>)})}</div></div>);
}export default App;

12.4发表评论

1.获取评论内容
const [content, setContent] = useState();<input type="text" value={content} onChange={(e) => setContent(e.target.value)}>2.点击发布按钮发布评论
const handlePublish = () => {setCommentList([...commentList,{name: user.uname,content: content,time: new Date(),likeNum: 0,uid: user.uid}])
}
<button onClick={handlePublish}></button>

在这里插入图片描述

  • 随机id可以使用uuid: git上搜索:uuidjs/uuid
    在这里插入图片描述
  • 日期时间格式化可以使用dayjs:dayjs官网:dayjs.gitee.io/zh-CN/
    在这里插入图片描述
    在这里插入图片描述

在这里插入图片描述

12.5清空内容并重新聚焦

在这里插入图片描述

import { useRef, useState } from 'react';
const [content, setContent] = useState(''); // 绑定input的value需要加初始值,否则会报错
const inputRef = useRef(null);
const handlePublish = () => {// ...做发布的逻辑// 1.清空输入框的内容setContent('');// 2.重新聚焦 dom(useRef) - focus()inputRef.current.focus();
}<input type="text" ref={inputRef} value={content} onChange={(e) => setContent(e.target.value)} />
<button onClick={handlePublish}>发布</button>

13.classnames工具优化类名控制

在这里插入图片描述
用classNames库之后使用方法:
在这里插入图片描述

1.命令安装classnames包
npm install classnames2.在组件中引入
import classNames from 'classname';3.在组件内使用, ‘’包裹的是静态的class, 
{// active是动态的class名,值是判断条件,是否需要加active这个classactive: type === item.type
}包裹的是动态的class从这样的:nav-item为静态class类名,active为动态class类名
<span className={`nav-item ${type === item.type && 'active'}`}>span...</span>变成这样:
<span className = {classNames('nav-item', {active: type === item.type
})}>span...</span>

在这里插入图片描述

相关文章:

react中JSX基础与useState的基本使用 + 评论显示删除需求案例

参考视频&#xff1a;https://www.bilibili.com/video/BV1ZB4y1Z7o8/?p3&spm_id_frompageDriver&vd_source5c584bd3b474d579d0bbbffdf0437c70 如果没有安装create-react-app需要先全局安装 命令&#xff1a;npm i -g create-react-app1.快速搭建开发环境 create-re…...

【OpenCV实现鼠标绘图,轨迹栏做调色板,图像的基本操作】

文章目录 鼠标绘图轨迹栏做调色板图像的基本操作 鼠标绘图 在OpenCV中操作鼠标事件 函数&#xff1a;cv.setMouseCallback() 目的是在鼠标双击的地方画一个圆。首先&#xff0c;我们需要创建一个鼠标回调函数&#xff0c;该函数会在鼠标事件发生时执行。鼠标事件包括左键按下…...

2023年中国自动排气阀产业链、市场规模及存在问题分析]图[

自动排气阀是一种用于排除管道、容器或设备中累积的空气或气体的装置。在液体流动系统中&#xff0c;气体或空气可能会积聚在管道或容器中&#xff0c;影响流体流动、导致气锁和能效降低。自动排气阀的作用是在系统中的气体达到一定压力时&#xff0c;自动地释放气体&#xff0…...

服务器往浏览器推消息(SSE)应用

1&#xff0c;SSE 和 WebSocket 对比 SSE&#xff08;服务器发送事件&#xff09; SSE是一种基于HTTP的单向通信机制&#xff0c;用于服务器向客户端推送数据。它的工作原理如下&#xff1a; 建立连接&#xff1a;客户端通过发送HTTP请求与服务器建立连接。在请求中&#xff…...

Choreographer

系统面试的时候常会遇到&#xff0c;比如它是什么&#xff0c;是用来做什么用的。或许我们大概清楚&#xff0c;但不一定能表达清楚。 在Android框架中&#xff0c;Choreographer&#xff08;舞台监督&#xff09;是一个用于管理和协调UI线程上的动画和绘制操作的系统组…...

CentOS有IP地址,连接不上Xshell或使用Xshell时突然断开

问题原因&#xff1a;未在电脑主机的网络中进行IP地址配置 解决办法&#xff1a; 1.打开控制面板&#xff0c;选择‘网络与共享中心’ 2.选择“更改适配器设置” 3.右键点击以太网3“属性” 4.选择协议版本4&#xff0c;点击属性 5.IP地址填写CentOS的IP地址&#xff1a;192.…...

工业电子中的深力科分享一款PWM控制器 KA3525A

关于PWM控制器&#xff1a; PWM控制器是一种用于控制电机或其他设备的电路&#xff0c;它通过改变脉冲宽度调制&#xff08;PWM&#xff09;信号的占空比来控制设备的输出。PWM控制器可以使用单片机或开发板等设备来实现&#xff0c;通过设定占空比&#xff0c;可以轻松地控制…...

【小白专用】安装Apache2.4+ 安装PHP8.2+ php与sql server 2008 r2连接测试教程

PHP安装 1、PHP下载 PHP For Windows: Binaries and sources Releases 注意&#xff1a; 1.要下载Thread Safe&#xff0c;否则没有php8apache2_4.dll这个文件 2.如果是64位系统要下载x64的&#xff0c;x86的不行 3.下载Zip 2、PHP解压安装 将Zip进行解压&#xff0c;里…...

408计算机网络知识点简记 (背诵用

1. 物理层 1. 奈氏和香农 意义不同:奈氏准则鼓励用更优编码码元(2W是码元/s);香农给出数据传输上限C(1. 不可能高过C,2. 若低于C,一定有手段做到C) C = W ∗ l o g 2 ( 1 + S N ) C =W * log_2(1+\frac{S}{N}) C=W∗log2​(1+NS​) 信噪比 = 10 ∗ l o g 10 ( S N …...

SQL*PLUS对文本长度的限制

SQL*PLUS对文本长度的限制 一、可解决SQL * Plus行长限制的部分选项&#xff1a;二、SQL * plus 因为以上限制导致脚本执行过程可能遇到的错误1、CLOB字段超4000报ORA-22835或ORA-017042、CLOB处理&#xff1a;SP2-0027: 输入太长 (> 2499 个字符) 收到错误SP2-0027&#xf…...

配置Insecure Docker Registry支持http请求 (更改默认的https请求)

文章目录 小结问题解决参考 小结 本文记录了如何配置Insecure http docker registry&#xff0c;也就是使用http请求 &#xff08;更改默认的https请求&#xff09;Docker Registry仓库。 问题 在测试环境中没有配置SSL/TLS&#xff0c; 需要使用http请求Docker Registry&am…...

BAT032:批量替换当前目录下文件的部分字符

引严&#xff1a;编写批处理程序&#xff0c;实现批量替换当前目录下文件的部分字符。 一、新建Windows批处理文件 参考博客&#xff1a; CSDNhttps://mp.csdn.net/mp_blog/creation/editor/132137544 二、写入批处理代码 1.右键新建的批处理文件&#xff0c;点击【编辑】。…...

uni-app:js实现数组中的相关处理

一、查询数组中&#xff0c;某一项中的某个数据为指定值的项&#xff08;find() 方法&#xff09; 使用分析 使用数组的 find() 方法来查询 id 为 0 的那一项数据。这个方法会返回满足条件的第一个元素&#xff0c;如果找不到符合条件的元素&#xff0c;则返回 undefined。使用…...

51系列—基于51单片机的数字频率计(代码+文档资料)

本文主要说明基于51单片机的数字频率计设计&#xff0c;完整资料见文末链接 数字频率计概述 数字频率计是计算机、通讯设备、音频视频等科研生产领域不可缺少的测量仪器。它是一种用十进制数字显示被测信号频率的数字测量仪器。它的基本功能是测量正弦信号&#xff0c;方波信…...

【SA8295P 源码分析 (四)】44 - 如何替换 NON-HLOS.bin 中的 Wifi Firmware 固件

【SA8295P 源码分析】44 - 如何替换 NON-HLOS.bin 中的 Wifi Firmware 固件 1、提取 NON-HLOS.bin 中的 Wifi Firmware 出来2、把提取出来的 wifi 固件放到代码中3、重新打包生成 NON-HLOS.bin4、将生成的 NON-HLOS.bin 与 老的 NON-HLOS.bin 对比5、使用fastboot 下载测试wifi…...

Aspect Android埋点统计activity页面使用时长 onResume onPause,并保存时长

Aspect Android埋点统计activity页面使用时长 onResume onPause&#xff0c;并保存时长 标记&#xff1a; 1.项目下build.gradle dependencies {classpath com.android.tools.build:gradle:3.5.4classpath com.hujiang.aspectjx:gradle-android-plugin-aspectjx:2.0.10 } 2.…...

第四章 选择结构程序设计

C语言有两种选择语句&#xff1a;&#xff08;1&#xff09;if语句&#xff0c;实现两个分支的选择结构&#xff1b; &#xff08;2&#xff09;Switch语句&#xff0c;实现多分支的选择结构。 1.求ax^2bxc0方程的解。 #include<stdio.h> #include<math.h> int …...

JAVA高级教程-Java List(2)

目录 3、List接口的使用&#xff08;1&#xff09;3、List接口的使用&#xff08;3&#xff09;4、排序&#xff0c;集合之间的转换 3、List接口的使用&#xff08;1&#xff09; package ArrayList01;import java.util.ArrayList; import java.util.Iterator; import java.ut…...

Spark--经典SQL50题

目录 连接数据库准备工作 1、查询"01"课程比"02"课程成绩高的学生的信息及课程分数 2、查询"01"课程比"02"课程成绩低的学生的信息及课程分数 3、查询平均成绩大于等于60分的同学的学生编号和学生姓名和平均成绩 4、查询平均成绩…...

数据结构: AVL树

目录 1.AVL树的概念 2.AVL树的模拟实现 AVL树的结构定义 插入 对平衡因子的讨论 旋转 对旋转情况的讨论 1.单旋 1.1左单旋 1.2右单旋 2.双旋 2.1左右双旋 2.2右左双旋 检查是否是AVL树 1.AVL树的概念 当向二叉搜索树中插入新结点后&#xff0c;如果能保证每个结点…...

荣耀WIN游戏本发布:散热、调校、屏幕全面升级,构建电竞与AI终端双生态

荣耀WIN游戏本&#xff1a;散热革新突破性能瓶颈2026年4月23日&#xff0c;荣耀在成都举办发布会&#xff0c;推出荣耀WIN游戏本系列等多款新品。荣耀WIN游戏本系列以创新的“24”轴流风扇散热结构和自研东风尾喷散热引擎&#xff0c;突破行业传统散热设计天花板。传统三风扇内…...

避坑指南:解决ptp4l报错‘failed to create a clock’的三种方法(附网卡支持检测)

深度解析ptp4l报错failed to create a clock的完整解决方案 当你在Linux系统上部署ptp4l进行高精度时间同步时&#xff0c;遇到"failed to create a clock"或"interface does not support requested timestamping mode"这类错误信息&#xff0c;往往意味着…...

别再只用最近邻了!CloudCompare点云距离计算的三种局部模型怎么选?

别再只用最近邻了&#xff01;CloudCompare点云距离计算的三种局部模型怎么选&#xff1f; 当你在CloudCompare中计算两个点云之间的距离时&#xff0c;是否经常直接使用默认的"最近邻"方法&#xff1f;这就像用锤子解决所有问题——有时有效&#xff0c;但更多时候会…...

别再只用groupby().mean()了!Pandas分组后agg、apply、transform的保姆级选择指南

Pandas分组操作进阶指南&#xff1a;如何精准选择agg/apply/transform方法 刚接触Pandas的groupby时&#xff0c;我们往往满足于简单的.mean()或.sum()操作。但随着数据分析需求复杂化&#xff0c;你会发现groupby后面跟着的agg、apply和transform这三个方法才是真正的"瑞…...

【最新评测】GPT Image 2 震撼发布:从「玩具」到「生产力」的跨越

2026年&#xff0c;OpenAI 的新一代图像生成模型 GPT Image 2 正式全量上线。从此前在 LM Arena 上以 maskingtape-alpha 等匿名代号意外泄露并引发测试者“集体干沉默”&#xff0c;到如今向大众开放&#xff0c;GPT Image 2 的登场让人直呼“现实不存在了”。如果说过去的 AI…...

Nature综述核心要点速览:肿瘤标志物深度解析

一、中国癌症形势&#xff1a;挑战与积极变化并存依据《JAMA》最新发布的流行病学数据统计分析&#xff0c;中国癌症发展态势依旧严峻。在特定研究周期内&#xff0c;男性有11种癌症、女性有14种癌症的年龄调整患病率显著攀升。具体而言&#xff0c;男性癌症中&#xff0c;甲状…...

Tiled地图编辑器架构深度解析:从插件系统到游戏引擎集成

Tiled地图编辑器架构深度解析&#xff1a;从插件系统到游戏引擎集成 【免费下载链接】tiled Flexible level editor 项目地址: https://gitcode.com/gh_mirrors/ti/tiled 在游戏开发领域&#xff0c;地图编辑器是连接美术资源和游戏逻辑的关键桥梁。然而&#xff0c;不同…...

保姆级教程:用Protege 5.5.0从零构建你的第一个知识图谱(附实战案例文件)

从零开始用Protege构建知识图谱&#xff1a;手把手实战指南 第一次打开Protege时&#xff0c;满屏的专业术语和复杂界面确实容易让人望而却步。但别担心&#xff0c;本文将带你像拼乐高一样&#xff0c;一步步搭建出你的第一个知识图谱。我们以"中国古代文人关系网"…...

从‘等效’到‘洞察’:用Multisim仿真深入理解电源变换与单口网络,避坑常见误区

从‘等效’到‘洞察’&#xff1a;用Multisim仿真深入理解电源变换与单口网络 在电路理论的学习中&#xff0c;等效变换是一个既基础又关键的概念。无论是电压源与电流源的相互转换&#xff0c;还是戴维宁与诺顿定理的应用&#xff0c;这些抽象的理论常常让初学者感到困惑。传统…...

Jenkins + Gerrit 自动化流水线实战:从代码提交到Verified标签的全链路配置

Jenkins Gerrit 自动化质量门禁实战&#xff1a;构建代码准入的全链路闭环 在DevOps实践中&#xff0c;代码质量门禁的自动化程度直接影响团队交付效率。当开发者将代码推送到Gerrit进行评审时&#xff0c;如何通过Jenkins自动执行验证流程&#xff0c;并根据结果动态更新Gerr…...