【React】详解“最新”和“最热”切换与排序

文章目录

    • 一、基本概念和初始化
    • 二、切换与排序功能的实现
      • 1. 函数定义和参数
      • 2. 设置活动 Tab
      • 3. 定义新列表变量
      • 4. 根据排序类型处理列表
        • 4.1 按时间降序排序
        • 4.2 按点赞数降序排序
      • 5. 更新评论列表
    • 三、渲染导航 Tab 和评论列表
      • 1. `map` 方法
      • 2. `key` 属性
      • 3. `className` 动态赋值
      • 4. `onClick` 事件处理器
      • 5. `item.text`
      • 6. `<li>` 容器
    • 四、进阶应用和实际案例
      • 1. 高亮 Tab 和排序状态管理
      • 2. 多条件排序

在现代网页应用中,评论列表是常见的功能模块。为了提高用户体验,我们经常需要对评论进行排序和筛选,以便用户能够更方便地找到感兴趣的内容。本文将深入探讨如何在 React 应用中实现“最新”和“最热”切换与排序功能,涵盖其基本用法、进阶应用以及实际案例。通过本文,你将全面了解如何在 React 应用中有效地实现评论排序功能,并灵活应用于实际项目中。

一、基本概念和初始化

评论数据和用户信息

首先,我们需要一些初始化的数据来展示评论列表。在下面的代码中,我们定义了一个包含评论数据的列表 defaultList 和一个模拟的当前用户 user

// 评论列表数据
const defaultList = [// 每个评论包含 id、用户信息、内容、时间和点赞数{rpid: 3,user: {uid: '13258165',avatar: '',uname: '周杰伦',},content: '哎哟,不错哦',ctime: '10-18 08:15',like: 88,},//....
];// 当前登录用户信息
const user = {uid: '30009257',avatar: 'path/to/avatar.png',uname: '黑马前端',
};

在这些数据中,defaultList 包含了评论的基本信息,包括评论 ID、用户信息、评论内容、时间和点赞数。

二、切换与排序功能的实现

在应用中,提供了两个导航选项卡(Tab):最热最新。用户可以通过点击这两个选项卡来切换评论的排序方式。

// 导航 Tab 数组
const tabs = [{ type: 'hot', text: '最热' },{ type: 'time', text: '最新' },
];

使用 useState 来管理当前选中的 Tab,并通过点击事件更新状态。onToggle 函数用于处理 Tab 的切换逻辑,并对评论列表进行相应的排序。

const [activeTab, setActiveTab] = useState('hot');
const [list, setList] = useState(defaultList);const onToggle = type => {setActiveTab(type);let newList;if (type === 'time') {// 按时间降序排序newList = orderBy(list, 'ctime', 'desc');} else {// 按点赞数降序排序newList = orderBy(list, 'like', 'desc');}setList(newList);
};

在这个函数中,orderBy 函数(来自 lodash 库)根据传入的排序字段(如 ctimelike)和排序顺序(降序)对评论列表进行排序,并更新状态。

1. 函数定义和参数

onToggle 是一个函数,接收一个参数 type,用于指定当前选中的排序类型。这个 type 参数可以是 'time''hot',分别代表“最新”和“最热”两种排序方式。

2. 设置活动 Tab

setActiveTab(type);
  • 功能:调用 setActiveTab 函数来更新当前活动的 Tab。
  • 作用:更新组件的状态,使得用户界面能够反映当前选中的排序方式。例如,如果用户点击了“最新”Tab,setActiveTab 会将 activeTab 的值更新为 'time',从而使得“最新”Tab 高亮显示。

3. 定义新列表变量

let newList;
  • 功能:声明一个变量 newList,用于存储排序后的评论列表。
  • 作用:这个变量将在根据 type 排序评论列表后被赋值。

4. 根据排序类型处理列表

4.1 按时间降序排序
if (type === 'time') {// 按时间降序排序newList = orderBy(list, 'ctime', 'desc');
}
  • 功能:检查 type 是否为 'time'
  • 作用:如果是 'time',则使用 orderBy 函数对 list(评论列表)按 ctime(评论时间)进行降序排序。orderBylodash 库中的一个函数,允许指定排序字段和排序顺序。
  • 具体操作:
    • list 是待排序的数组。
    • 'ctime' 是排序字段,即按照评论时间排序。
    • 'desc' 指定排序顺序为降序。
4.2 按点赞数降序排序
else {// 按点赞数降序排序newList = orderBy(list, 'like', 'desc');
}
  • 功能:如果 type 不是 'time',则认为排序方式是按点赞数排序。
  • 作用:使用 orderBy 函数对 listlike(点赞数)进行降序排序。
  • 具体操作:
    • list 是待排序的数组。
    • 'like' 是排序字段,即按照点赞数排序。
    • 'desc' 指定排序顺序为降序。

5. 更新评论列表

setList(newList);
  • 功能:调用 setList 函数来更新组件状态中的评论列表。
  • 作用:将排序后的 newList 更新到组件状态中,从而使得评论列表的显示顺序根据用户的选择进行更新。

三、渲染导航 Tab 和评论列表

在组件的返回 JSX 中,渲染了 Tab 切换按钮和评论列表。点击 Tab 按钮会触发 onToggle 函数,更新排序方式。

return (<div className="app">{/* 导航 Tab */}<div className="reply-navigation"><ul className="nav-bar"><li className="nav-title"><span className="nav-title-text">评论</span><span className="total-reply">{list.length}</span></li><li className="nav-sort">{tabs.map(item => (<divkey={item.type}className={item.type === activeTab ? 'nav-item active' : 'nav-item'}onClick={() => onToggle(item.type)}>{item.text}</div>))}</li></ul></div>{/* 评论列表 */}<div className="reply-list">{list.map(item => (<div key={item.rpid} className="reply-item"><div className="root-reply-avatar"><img className="bili-avatar-img" src={item.user.avatar} alt="" /></div><div className="content-wrap"><div className="user-info"><div className="user-name">{item.user.uname}</div></div><div className="root-reply"><span className="reply-content">{item.content}</span><div className="reply-info"><span className="reply-time">{item.ctime}</span><span className="reply-time">点赞数:{item.like}</span>{user.uid === item.user.uid && (<span className="delete-btn" onClick={() => onDelete(item.rpid)}>删除</span>)}</div></div></div></div>))}</div></div>
);

在这个 JSX 代码中,我们使用条件渲染来应用选中的 Tab 的高亮样式,并通过 onClick 事件绑定到 onToggle 函数,以实现 Tab 切换功能。评论列表的渲染则根据当前的排序方式显示评论项。

1. map 方法

tabs.map(item => (...)) 使用了 Array.prototype.map 方法遍历 tabs 数组,并为每个 item 返回一个 <div> 元素。map 方法会根据数组中的每个元素生成一个新的数组,新的数组中的每个元素是一个 <div> 元素。

2. key 属性

key={item.type}
  • 功能key 属性用于标识数组中每个元素的唯一性,以便 React 能够高效地更新和渲染列表。
  • 作用:这里使用 item.type 作为每个 <div> 元素的 key,因为 type 是唯一的('hot''time')。

3. className 动态赋值

className={item.type === activeTab ? 'nav-item active' : 'nav-item'}
  • 功能:根据当前活动的 Tab (activeTab) 动态设置 <div> 元素的 className
  • 作用:如果当前 item.type 等于 activeTab,则为该 <div> 元素添加 nav-item active 类,使其显示为活动状态(高亮)。否则,仅添加 nav-item 类。

4. onClick 事件处理器

onClick={() => onToggle(item.type)}
  • 功能:为 <div> 元素添加 onClick 事件处理器。
  • 作用:当用户点击某个 Tab 时,调用 onToggle 函数,并将当前 item.type 作为参数传递给 onToggle 函数,从而触发排序逻辑的切换。

5. item.text

{item.text}
  • 功能:在每个 <div> 元素内显示 item.text 的内容。
  • 作用:显示 Tab 文本,分别为“最热”和“最新”。

6. <li> 容器

<li className="nav-sort">...
</li>
  • 功能:将所有生成的 <div> 元素包含在一个 <li> 元素内,并为其添加 nav-sort 类。
  • 作用:作为导航栏的一部分,用于包含和布局所有 Tab 选项。

四、进阶应用和实际案例

1. 高亮 Tab 和排序状态管理

在实际应用中,可能需要根据用户的操作保存和恢复排序状态。例如,在用户切换到“最新”标签后,我们可以保持这个状态,以便用户刷新页面后仍能看到上次选择的排序方式。这可以通过浏览器的本地存储(localStorage)来实现。

useEffect(() => {const savedTab = localStorage.getItem('activeTab') || 'hot';setActiveTab(savedTab);
}, []);useEffect(() => {localStorage.setItem('activeTab', activeTab);
}, [activeTab]);

2. 多条件排序

在某些复杂场景下,可能需要进行多条件排序。例如,用户可能希望首先按点赞数排序,然后再按时间排序。这种情况下,可以扩展排序逻辑以支持多条件排序。

const onToggle = type => {setActiveTab(type);let newList;if (type === 'time') {newList = orderBy(list, ['ctime', 'like'], ['desc', 'desc']);} else {newList = orderBy(list, ['like', 'ctime'], ['desc', 'desc']);}setList(newList);
};

代码源


在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/385108.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

模式Hash和history

vuerouter有两种路由模式Hash和history。区别&#xff1a;Hash为默认模式&#xff0c;url中包含一个#符号的哈希部分。优势&#xff1a;兼容性好&#xff0c;不需要后端服务器的特殊配置。缺点&#xff1a;不够美观&#xff0c;搜索引擎优化较差。History模式使用的浏览器的His…

小程序多排数据横向滚动实现

如何实现多排数据滚动效果 swiper 外部容器 swiper-item 每一页的数据 因为现在有多排数据,现在在swiper-item 中需要循环一个数组 初版 <template><view><view class"container"><view class"swiper-box"><swiper class&qu…

《Utilizing Ensemble Learning for Detecting Multi-Modal Fake News》

系列论文研读目录 文章目录 系列论文研读目录论文题目含义ABSTRACTINDEX TERMSI. INTRODUCTIONII. RELATED WORKA. FAKE NEWS CLASSIFICATION APPROACHES FOR SINGLE-MODALITY 单模态虚假新闻分类方法1) SINGLE-MODALITY BASED CLASSIFICATION APPROACHES USING TEXTUAL FEATUR…

家政项目小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;家政人员管理&#xff0c;家政服务管理&#xff0c;咨询信息管理&#xff0c;咨询服务管理&#xff0c;家政预约管理&#xff0c;留言板管理&#xff0c;系统管理 微信端账号功能…

Servlet1-Servlet程序、请求处理、继承体系

目录 什么是Servlet 手动实现Servlet程序 ​编辑url地址如何定位到Servlet程序去访问 Servlet的生命周期 ​编辑GET和POST请求的分发处理 通过继承HttpServlet类实现Servlet程序 IDEA菜单生成Servlet程序 Servlet类的继承体系 ServletConfig类 ServletContext类 什么…

go语言day19 使用git上传包文件到github Gin框架入门

git分布式版本控制系统_git切换head指针-CSDN博客 获取请求参数并和struct结构体绑定_哔哩哔哩_bilibili &#xff08;gin框架&#xff09; GO: 引入GIn框架_go 引入 gin-CSDN博客 使用git上传包文件 1&#xff09;创建一个github账户&#xff0c;进入Repositories个人仓…

新能源充电桩结构设计的核心要素

充电桩结构设计的核心要素 一、外观设计 外观设计对于用户体验和充电站的可接受性具有举足轻重的地位。其设计应遵循现代化、直观易懂的原则&#xff0c;同时符合人机工程学原理&#xff0c;以确保用户操作的便捷性。此外&#xff0c;外观设计还需与城市规划和环境美学相协调…

特斯拉财报看点:FSD拳打华为,Robotaxi 脚踢百度

大数据产业创新服务媒体 ——聚焦数据 改变商业 特斯拉发最新财报了&#xff0c;这不仅是一份财务报告&#xff0c;更是一张未来发展的蓝图。在这份蓝图中&#xff0c;两个关键词格外耀眼——FSD&#xff08;全自动驾驶系统&#xff09;和Robotaxi&#xff08;无人驾驶出租车&…

Linux_权限3

Linux所对应的文件类型 1.在Win下&#xff0c;有文件类型&#xff0c;通常通过后缀标识 日常用的就是windows系统这里不做举例. 2.Linux的文件类型不通过后缀区分&#xff08;不代表Linux不用后缀) 其中需要注意的是第一个字符表示文件类型的含义 - :普通文件, 文本, 源代码…

C++初学(2)

2.1、其他简单C语句例子 下面这个程序要求运行时输入值 #include <iostream> int main() {using namespace std;int yuanshi;cout << "How many yuanshi do you have?" << endl;cin >> yuanshi;cout << "Here are two more.&q…

高频面试题基本总结回顾(含笔试高频算法整理,暂存)

干货分享&#xff0c;感谢您的阅读&#xff01; &#xff08;暂存篇---后续会删除&#xff0c;完整版和持续更新见高频面试题基本总结回顾&#xff08;含笔试高频算法整理&#xff09;&#xff09; 备注&#xff1a;引用请标注出处&#xff0c;同时存在的问题请在相关博客留言…

简单的CSS样式

样式分为三种 内部样式&#xff1a;写在html文件里的样式叫内部样式 内联样式&#xff1a;写在需要的标签中 外部样式&#xff1a;写在外部css文件里 可以通过不同的选择器来选择设置指定组件的样式&#xff1a; <style>/* 写在html文件里的样式叫内部样式 *//* 选择器 *…

C语言强化-3.单链表的新建、查找

与408的关联&#xff1a;1. 链表出了很多大题。 2. 任何数据结构&#xff0c;主要进行的操作就是增删改查。 头插法新建链表的实战 流程图 代码 #include <stdio.h> #include <stdlib.h>typedef int ElemType; typedef struct LNode{ElemType data;//数据域struc…

视频生成【文章汇总】SVD, Sora, Latte, VideoCrafter12, DiT...

视频生成【文章汇总】SVD, Sora, Latte, VideoCrafter12, DiT... 数据集指标 【arXiv 2024】MiraData: A Large-Scale Video Dataset with Long Durations and Structured Captions【CVPR 2024】VBench : Comprehensive Benchmark Suite for Video Generative Models【arxiv 20…

微信小程序支付流程

前端需要做的事情&#xff1a; 生成平台订单&#xff1a;前端调用接口&#xff0c;向后端传递购买的商品信息、收货人信息&#xff0c;&#xff08;后端生成平台订单&#xff0c;返回订单编号&#xff09;获取预付单信息&#xff1a;将订单编号发送给后端后&#xff0c;&#x…

我在Vscode学Java泛型(泛型设计、擦除、通配符)

Java泛型 一、泛型 Generics的意义1.1 在没有泛型的时候&#xff0c;集合如何存储数据1.2 引入泛型的好处1.3 注意事项1.3.1 泛型不支持基本数据类型1.3.2 当泛型指定类型&#xff0c;传递数据时可传入该类及其子类类型1.3.3 如果不写泛型&#xff0c;类型默认是Object 二、泛型…

.net 连接达梦数据库开发环境部署

.net 开发环境部署 1. 环境准备 测试工具 Visual Studio2022 数据库版本 dm8 2. 搭建过程 1 &#xff09;创建新项目 2 &#xff09;选择创建空项目 3 &#xff09;配置新项目 4 &#xff09;右键 DM1 新建一个项 5 &#xff09;加 载 驱 动 &#xff0c; 新 建 …

SQL labs-SQL注入(五,使用sqlmap进行cookie注入)

本文仅作为学习参考使用&#xff0c;本文作者对任何使用本文进行渗透攻击破坏不负任何责任。 引言&#xff1a; Cookie 是一些数据, 存储于你电脑上的文本文件中。当 web 服务器向浏览器发送 web 页面时&#xff0c;在连接关闭后&#xff0c;服务端不会记录用户的信息。Cookie…

加速决策过程:企业级爬虫平台的实时数据分析

摘要 在当今数据驱动的商业环境中&#xff0c;企业如何才能在海量信息中迅速做出精准决策&#xff1f;本文将探讨企业级爬虫平台如何通过实时数据分析加速决策过程&#xff0c;实现数据到决策的无缝衔接。我们聚焦于技术如何赋能企业&#xff0c;提升数据处理效率&#xff0c;…

RK3568 Linux 平台开发系列讲解(内核入门篇):从内核的角度看外设芯片的驱动

在嵌入式 Linux 开发中,外设芯片的驱动是实现操作系统与硬件之间交互的关键环节。对于 RK3568 这样的处理器平台,理解如何从内核的角度构建和管理外设芯片的驱动程序至关重要。 1. 外设驱动的基础概念 外设驱动(Device Driver)是操作系统与硬件设备之间的桥梁。它负责控…