当前位置: 首页 > 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;如果能保证每个结点…...

Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务

通过akshare库&#xff0c;获取股票数据&#xff0c;并生成TabPFN这个模型 可以识别、处理的格式&#xff0c;写一个完整的预处理示例&#xff0c;并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务&#xff0c;进行预测并输…...

PL0语法,分析器实现!

简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...

工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配

AI3D视觉的工业赋能者 迁移科技成立于2017年&#xff0c;作为行业领先的3D工业相机及视觉系统供应商&#xff0c;累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成&#xff0c;通过稳定、易用、高回报的AI3D视觉系统&#xff0c;为汽车、新能源、金属制造等行…...

什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南

文章目录 什么是X11?环境准备实战步骤1️⃣ 服务器端配置(CentOS)2️⃣ 客户端配置(MobaXterm)3️⃣ 验证X11 Forwarding4️⃣ 运行自定义GUI程序(Python示例)5️⃣ 成功效果![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/55aefaea8a9f477e86d065227851fe3d.pn…...

深度学习水论文:mamba+图像增强

&#x1f9c0;当前视觉领域对高效长序列建模需求激增&#xff0c;对Mamba图像增强这方向的研究自然也逐渐火热。原因在于其高效长程建模&#xff0c;以及动态计算优势&#xff0c;在图像质量提升和细节恢复方面有难以替代的作用。 &#x1f9c0;因此短时间内&#xff0c;就有不…...

【Redis】笔记|第8节|大厂高并发缓存架构实战与优化

缓存架构 代码结构 代码详情 功能点&#xff1a; 多级缓存&#xff0c;先查本地缓存&#xff0c;再查Redis&#xff0c;最后才查数据库热点数据重建逻辑使用分布式锁&#xff0c;二次查询更新缓存采用读写锁提升性能采用Redis的发布订阅机制通知所有实例更新本地缓存适用读多…...

并发编程 - go版

1.并发编程基础概念 进程和线程 A. 进程是程序在操作系统中的一次执行过程&#xff0c;系统进行资源分配和调度的一个独立单位。B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。C.一个进程可以创建和撤销多个线程;同一个进程中…...

实战三:开发网页端界面完成黑白视频转为彩色视频

​一、需求描述 设计一个简单的视频上色应用&#xff0c;用户可以通过网页界面上传黑白视频&#xff0c;系统会自动将其转换为彩色视频。整个过程对用户来说非常简单直观&#xff0c;不需要了解技术细节。 效果图 ​二、实现思路 总体思路&#xff1a; 用户通过Gradio界面上…...

协议转换利器,profinet转ethercat网关的两大派系,各有千秋

随着工业以太网的发展&#xff0c;其高效、便捷、协议开放、易于冗余等诸多优点&#xff0c;被越来越多的工业现场所采用。西门子SIMATIC S7-1200/1500系列PLC集成有Profinet接口&#xff0c;具有实时性、开放性&#xff0c;使用TCP/IP和IT标准&#xff0c;符合基于工业以太网的…...

JDK 17 序列化是怎么回事

如何序列化&#xff1f;其实很简单&#xff0c;就是根据每个类型&#xff0c;用工厂类调用。逐个完成。 没什么漂亮的代码&#xff0c;只有有效、稳定的代码。 代码中调用toJson toJson 代码 mapper.writeValueAsString ObjectMapper DefaultSerializerProvider 一堆实…...