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

【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);
};

代码源


在这里插入图片描述

相关文章:

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

文章目录 一、基本概念和初始化二、切换与排序功能的实现1. 函数定义和参数2. 设置活动 Tab3. 定义新列表变量4. 根据排序类型处理列表4.1 按时间降序排序4.2 按点赞数降序排序 5. 更新评论列表 三、渲染导航 Tab 和评论列表1. map 方法2. key 属性3. className 动态赋值4. onC…...

BUUCTF [MRCTF2020]Ezpop

这道题对于刚接触到pop链的我直接把我整懵了&#xff0c;一边看着魔术方法一边分析 魔术方法可以看这里PHP 魔术方法 - 简介 - PHP 魔术方法 - 简单教程&#xff0c;简单编程 (twle.cn) 代码解析 经过以上的分析我们可以理一下解题思路&#xff1a;接收参数反序列化之前先触发…...

RV1126 Linux 系统,接外设,时好时坏(一)应该从哪些方面排查问题

在 Linux 系统中接外设时,遇到“时好时坏”的问题,可能是由多种因素引起的。以下是一些排查问题的建议。 1. 硬件方面的排查 1.1 连接检查 物理连接: 确保外设与主板之间的连接良好,检查插头、插座及线缆是否牢固。引脚配置: 确认设备树中引脚的配置是否正确,尤其是引脚…...

Vue实现简单小案例

一、创建文件夹 二、引用vue.js <script src"../js/vue.js"></script> 三、准备一个容器 <div id"app"><h1>Hello,{{name}}</h1> </div> 四、创建实例 <script>new Vue({el:"#app", //el用于指…...

【MATLAB APP】建立独立桌面APP

背景&#xff1a;已有MATLAB APP的.mlapp文件&#xff0c;但客户提出需要可以直接使用的exe文件。 要求&#xff1a;点开即用&#xff0c;无需下载MATLAB。使用者无法修改APP的代码。 一、环境配置 APP创建者&#xff1a;安装MATLAB R2023a&#xff0c;配置Application Compile…...

Spring的优缺点?

Spring的优缺点 直接回答相关的Spring的特点&#xff1a; IOC AOP 事务 简化开发&#xff1a; 容易集成JDBCTemplateRestTemplate&#xff08;接口远程调用&#xff09;邮件发送相关异步消息请求支持 更加深入就讲源码了 优点&#xff1a; 方便解耦&#xff0c;简化开发…...

第一百八十三节 Java IO教程 - Java目录事件、Java异步I/O

Java IO教程 - Java目录事件 当文件系统中的对象被修改时&#xff0c;我们可以监听watch服务以获取警报。 java.nio.file包中的以下类和接口提供watch服务。 Watchable接口WatchService接口WatchKey接口WatchEvent接口WatchEvent.Kind接口StandardWatchEventKinds类 可监视对…...

【设计模式】(万字总结)深入理解Java中的创建型设计模式

1. 前言 在软件开发的世界里&#xff0c;设计模式是一种被广泛接受并应用的解决方案。它们不仅仅是代码的设计&#xff0c;更是对问题的思考和解决的方法论。在Java开发中&#xff0c;特别是在面向对象的编程中&#xff0c;设计模式尤为重要。创建型设计模式&#xff0c;作为设…...

【全面讲解下Docker in Docker的原理与实践】

🌈个人主页: 程序员不想敲代码啊 🏆CSDN优质创作者,CSDN实力新星,CSDN博客专家 👍点赞⭐评论⭐收藏 🤝希望本文对您有所裨益,如有不足之处,欢迎在评论区提出指正,让我们共同学习、交流进步! 👉目录 👉前言👉原理👉实践👉安全和最佳实践👉前言 🦛…...

Android Settings增加多击事件,增加开发者模式打开难度

软件平台&#xff1a;Android11 硬件平台&#xff1a;QCS6125 需求来源&#xff1a;用户通过系统异常崩溃&#xff0c;进入原生Settings页面&#xff0c;通过默认的多击版本号方式打开开发者模式&#xff0c;继而打开adb调试开关&#xff0c;安装三方apk。 对付这种需求本来有…...

【相机与图像】1. 相机模型的介绍:内参、外参、畸变参数

想着整理下相机模型&#xff08;内容上参考 slam十四讲&#xff09;、相机的内外参标定。方便自己的使用和回顾。 不过&#xff0c;内外参标定啥时候记录随缘 -_- 概述 【构建相机模型】 相机将三位世界中的坐标点&#xff08;单位为米&#xff09;映射到二维图像平面&#xff…...

Linux内核netlink机制 - 用户空间和内核空间数据传输

简介&#xff1a; Netlink socket 是一种Linux特有的socket&#xff0c;用于实现用户空间与内核空间通信的一种特殊的进程间通信方式(IPC) &#xff0c;也是网络应用程序与内核通信的最常用的接口。 Netlink 是一种在内核和用户应用间进行双向数据传输的非常好的方式&a…...

Node.js自动化处理TOML文件

在软件开发过程中&#xff0c;自动化处理配置文件是一种常见的需求。TOML&#xff08;Tom’s Obvious, Minimal Language&#xff09;是一种用于配置文件的简单易读的格式。本文将展示如何使用Node.js和一些流行的库来自动化读取、修改并写入TOML文件。 1. 准备工作 在开始之前…...

Spring boot 后端向前端发送日期时间发现少了8小时

问题 数据库 后端的控制台输出 前端控制台输出 可以发现少了8小时 问题 springboot 向前端响应数据是默认 Json 格式&#xff0c;所以会有类型转换&#xff0c;springboot 就通过 Jackson 来对 data 类型数据进行转换&#xff0c;但是Jackson 类型的时区是 GMT&#xff0c;与…...

MySQL数据库(基础篇)

&#x1f30f;个人博客主页&#xff1a;心.c 前言&#xff1a;今天讲解的是MySQL的详细知识点的&#xff0c;希望大家可以收货满满&#xff0c;话不多说&#xff0c;直接开始搞&#xff01; &#x1f525;&#x1f525;&#x1f525;文章专题&#xff1a;MySQL &#x1f63d;感…...

ffmpeg ffplay.c 源码分析二:数据读取线程

本章主要是分析 数据读取线程read_thread 中的工作。如上图红色框框的部分 从ffplay框架分析我们可以看到&#xff0c;ffplay有专⻔的线程read_thread()读取数据&#xff0c; 且在调⽤av_read_frame 读取数据包之前需要做&#xff1a; 1.例如打开⽂件&#xff0c; 2.查找配置解…...

国科大作业考试资料《人工智能原理与算法》2024新编-第十三次作业整理

1、假设我们从决策树生成了一个训练集&#xff0c;然后将决策树学习应用于该训练集。当训练集的大小趋于无穷时&#xff0c;学习算法将最终返回正确的决策树吗&#xff1f;为什么是或不是&#xff1f; 本次有两个参考&#xff1a; 参考一&#xff1a; 当训练集的大小趋于无穷…...

Netdevops入门之Telnetlib语法案例

1、Telnetlib模块&#xff1a; 支持telnet/ssh远程访问的模块很多&#xff0c;常见的有telnetlib、ciscolib、paramiko、netmiko、pexpect,其中telnetlib和ciscolib对应telnet协议&#xff0c;后面3个对应SSH协议。 ①-通过ENSP环境搭建实验环境 ②-基础语法-telnetlib案例1&…...

永辉“爆改”续命

2024年&#xff0c;在线下零售一片哀嚎之下&#xff0c;胖东来似乎活成了国内零售业的密码&#xff0c;同时也变身成为各大零售企业的咨询公司&#xff0c;四处帮助“友商”救火&#xff0c;就连一直名声在外的永辉超市&#xff0c;也成了救火对象。 作为曾经国内生鲜超市的“…...

IEEE双一区Top“饱受诟病”!曾上医院黑名单,国人占比高达82.405%,目测即将拉下神坛?

本周投稿推荐 SCI&EI • 1区计算机类&#xff0c;3.5-4.0&#xff08;1个月录用&#xff09; • CCF推荐&#xff0c;1区-Top&#xff08;3天初审&#xff09; EI • 各领域沾边均可&#xff08;2天录用&#xff09; 知网&#xff08;CNKI&#xff09;、谷歌学术 •…...

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...

Leetcode 3576. Transform Array to All Equal Elements

Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接&#xff1a;3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到&#xf…...

DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI

前一阵子在百度 AI 开发者大会上&#xff0c;看到基于小智 AI DIY 玩具的演示&#xff0c;感觉有点意思&#xff0c;想着自己也来试试。 如果只是想烧录现成的固件&#xff0c;乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外&#xff0c;还提供了基于网页版的 ESP LA…...

C++八股 —— 单例模式

文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全&#xff08;Thread Safety&#xff09; 线程安全是指在多线程环境下&#xff0c;某个函数、类或代码片段能够被多个线程同时调用时&#xff0c;仍能保证数据的一致性和逻辑的正确性&#xf…...

有限自动机到正规文法转换器v1.0

1 项目简介 这是一个功能强大的有限自动机&#xff08;Finite Automaton, FA&#xff09;到正规文法&#xff08;Regular Grammar&#xff09;转换器&#xff0c;它配备了一个直观且完整的图形用户界面&#xff0c;使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...

Java线上CPU飙高问题排查全指南

一、引言 在Java应用的线上运行环境中&#xff0c;CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时&#xff0c;通常会导致应用响应缓慢&#xff0c;甚至服务不可用&#xff0c;严重影响用户体验和业务运行。因此&#xff0c;掌握一套科学有效的CPU飙高问题排查方法&…...

#Uniapp篇:chrome调试unapp适配

chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器&#xff1a;Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...

【分享】推荐一些办公小工具

1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由&#xff1a;大部分的转换软件需要收费&#xff0c;要么功能不齐全&#xff0c;而开会员又用不了几次浪费钱&#xff0c;借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...

Linux系统部署KES

1、安装准备 1.版本说明V008R006C009B0014 V008&#xff1a;是version产品的大版本。 R006&#xff1a;是release产品特性版本。 C009&#xff1a;是通用版 B0014&#xff1a;是build开发过程中的构建版本2.硬件要求 #安全版和企业版 内存&#xff1a;1GB 以上 硬盘&#xf…...

C++实现分布式网络通信框架RPC(2)——rpc发布端

有了上篇文章的项目的基本知识的了解&#xff0c;现在我们就开始构建项目。 目录 一、构建工程目录 二、本地服务发布成RPC服务 2.1理解RPC发布 2.2实现 三、Mprpc框架的基础类设计 3.1框架的初始化类 MprpcApplication 代码实现 3.2读取配置文件类 MprpcConfig 代码实现…...