【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://xiahunao.cn/news/3268249.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

Spring Cloud Gateway网关的高级特性以及配置之Route Predicate Factories(路由谓词工厂)

一、Route Predicate Factories&#xff08;路由谓词工厂&#xff09; 还是先来查看官网的说明&#xff1a;点击此处 路由谓词工厂是微服务网关&#xff08;如Spring Cloud Gateway&#xff09;中用于定义路由规则的一种机制。它们用来决定哪些请求应该被路由到特定的服务。 …

web学习笔记(八十三)git

目录 1.Git的基本概念 2.gitee常用的命令 3.解决两个人操作不同文件造成的冲突 4.解决两个人操作同一个文件造成的冲突 1.Git的基本概念 git是一种管理代码的方式&#xff0c;广泛用于软件开发和版本管理。我们通常使用gitee&#xff08;码云&#xff09;来云管理代码。 …

鸿蒙(API 12 Beta2版)【创建NDK工程】

创建NDK工程 下面通过DevEco Studio的NDK工程模板&#xff0c;来演示如何创建一个NDK工程。 说明 不同DevEco Studio版本的向导界面、模板默认参数等会有所不同&#xff0c;请根据实际工程需要&#xff0c;创建工程或修改工程参数。 通过如下两种方式&#xff0c;打开工程创…

【资料分享】2024钉钉杯大数据挑战赛A题思路解析+代码演示

2024第三届钉钉杯大学生大数据挑战赛今天已经开赛&#xff0c;【A题】思路解析代码&#xff0c;资料预览&#xff1a;

【数据结构】二叉树链式结构——感受递归的暴力美学

前言&#xff1a; 在上篇文章【数据结构】二叉树——顺序结构——堆及其实现中&#xff0c;实现了二叉树的顺序结构&#xff0c;使用堆来实现了二叉树这样一个数据结构&#xff1b;现在就来实现而二叉树的链式结构。 一、链式结构 链式结构&#xff0c;使用链表来表示一颗二叉树…

Python 爬虫入门(一):从零开始学爬虫 「详细介绍」

Python 爬虫入门&#xff08;一&#xff09;&#xff1a;从零开始学爬虫 「详细介绍」 前言1.爬虫概念1.1 什么是爬虫&#xff1f;1.2 爬虫的工作原理 2. HTTP 简述2.1 什么是 HTTP&#xff1f;2.2 HTTP 请求2.3 HTTP 响应2.4 常见的 HTTP 方法 3. 网页的组成3.1 HTML3.1.1 HTM…

【MATLAB源码-第238期】基于simulink的三输出单端反激flyback仿真,通过PWM和PID控制能够得到稳定电压。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 概述 反激变换器是一种广泛应用于电源管理的拓扑结构&#xff0c;特别是在需要隔离输入和输出的应用中。它的工作原理是利用变压器的储能和释放能量来实现电压转换和隔离。该图展示了一个通过脉宽调制&#xff08;PWM&#…

基于springboot+vue+uniapp的居民健康监测小程序

开发语言&#xff1a;Java框架&#xff1a;springbootuniappJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#…

【初阶数据结构】9.二叉树(4)

文章目录 5.二叉树算法题5.1 单值二叉树5.2 相同的树5.3 另一棵树的子树5.4 二叉树遍历5.5 二叉树的构建及遍历 6.二叉树选择题 5.二叉树算法题 5.1 单值二叉树 点击链接做题 代码&#xff1a; /*** Definition for a binary tree node.* struct TreeNode {* int val;* …

虚拟机centos9搭建wordpress

目录 1. 更换yum源更新系统软件包&#xff1a; 1.1备份yum源 1.1.1创建备份目录&#xff1a; 1.1.2移动现有仓库配置文件到备份目录&#xff1a; 1.1.3验证备份&#xff1a; 1.2更换yum源 1.2.1添加yum源 1.2.2删除和建立yum缓存 1.3更新系统软件包 1.4 yum与dnf介绍…

谷粒商城实战笔记-62-商品服务-API-品牌管理-OSS整合测试

文章目录 一&#xff0c;Java中上传文件到阿里云OSS1&#xff0c;整合阿里云OSS2&#xff0c;测试上传文件 二&#xff0c;Java中整合阿里云OSS服务指南引言准备工作1. 注册阿里云账号2. 获取Access Key3. 添加依赖 实现OSS客户端1. 初始化OSSClient2. 创建Bucket3. 上传文件4.…

nginx的学习(二):负载均衡和动静分离

简介 nginx的负载均衡和动静分离的简单使用 负载均衡配置 外部访问linux的ip地址:80/edu/a.html地址&#xff0c;会轮询访问Tomcat8080和Tomcat8081服务。 Tomcat的准备 准备两个Tomcat&#xff0c;具体准备步骤在nginx的学习一的反向代理例子2中&#xff0c;在Tomcat8080…

告别繁琐地推!Xinstall如何一键优化你的App地推方案

在这个移动应用遍地开花的时代&#xff0c;App地推活动早已成为各大厂商获取新用户、提升品牌曝光度的重要手段。然而&#xff0c;传统地推方案中的种种弊端&#xff0c;如填写地推码/邀请码的繁琐、渠道打包的工作量繁重、人工登记上报的不准确等&#xff0c;无一不在拖慢地推…

【接口设计】学会用 RestTemplate 发请求

《接口设计》系列&#xff0c;共包含以下 5 篇文章&#xff1a; 前后端的通信方式 REST如何设计统一 RESTful 风格的数据接口为 APP、PC、H5 网页提供统一风格的 API&#xff08;实战篇&#xff0c;附源码地址&#xff09;用 Swagger 实现接口文档学会用 RestTemplate 发请求 …

【C++】选择结构案例-三目运算符

三目运算符语法格式&#xff1a; 布尔表达式?表达式1:表达式2 运算过程&#xff1a;如果布尔表达式的值为 true &#xff0c;则返回 表达式1 的值&#xff0c;否则返回 表达式2 的值 &#xff08;三目运算符指的是&#xff1f;和&#xff1a;&#xff09; 在这个三目运算符…

USB转多路串口-纯硬件实现串口数据传输指示灯电路

前言 串口相关产品往往要求有数据收发时LED闪烁&#xff0c;我们经常会用软件实现&#xff0c;在MCU内注册一个定时器&#xff0c;有数据发送时就闪烁一段时间。软件点灯这种方式存在两个缺陷&#xff0c;一是接收方向不好实现&#xff1b;二是定时器一般用固定频率&#xff0…

Redis的两种持久化方式---RDB、AOF

rdb其实就是一种快照持久化的方式&#xff0c;它会将Redis在某个时间点的所有的数据状态以二进制的方式保存到硬盘上的文件当中&#xff0c;它相对于aof文件会小很多&#xff0c;因为知识某个时间点的数据&#xff0c;当然&#xff0c;这就会导致它的实时性不够高&#xff0c;如…

Nature Electronics|柔性可吞服电子设备用于胃部电生理学监测(柔性健康监测/可吞服电子/柔性

美国麻省理工学院David H. Koch 综合癌症研究所的 Giovanni Traverso团队,在《Nature Electronics》上发布了一篇题为“An ingestible device for gastric electrophysiology”的论文。论文内容如下: 一、 摘要 从胃肠道和肠道神经系统记录高质量电生理数据的能力有助于了解…

信通院发布!首个大模型混合云标准

近日&#xff0c;中国信通院发布了首个大模型混合云标准&#xff0c;通过定位当前大模型混合云的能力水平&#xff0c;为基于混合云的大模型服务实践提供指引&#xff0c;并明确未来提升方向。同时&#xff0c;中国信通院基于标准展开大模型混合云能力成熟度专项测试&#xff0…

生信技能54 - WisecondorX多线程并行分析CNV

WisecondorX分析CNV,默认单样本分析,batch_analysis参数设置为True可启动多样本并行分析。 WisecondorX基本使用方法以及npz文件转换和reference构建参考文章: 生信技能53 - wiseconrdoX自动化批量npz转换和reference构建 github: https://github.com/CenterForMedicalGe…