ReactJS教程:如何实现点击单个职位显示详情

ReactJS教程:如何实现点击单个职位显示详情

本教程旨在解决reactjs应用中列表项交互的常见问题:当点击一个列表项(如职位发布)时,如何确保只有被点击的项显示其详细信息,而不是所有项都同时显示。我们将通过“状态提升”模式,在父组件中管理当前选中项的id,并将其作为布尔值属性传递给子组件,从而实现精准的条件渲染。

在构建交互式Web应用时,尤其是涉及列表展示的场景,经常会遇到需要点击某个列表项来显示或隐藏其特定内容的业务需求。一个常见的陷阱是,如果使用一个全局的布尔状态变量来控制所有列表项的显示/隐藏,那么当该状态改变时,所有列表项都会同时响应,导致非预期的行为。例如,在一个职位公告板应用中,点击一个职位却使得所有职位的详情都展开了。

理解问题根源

在提供的原始代码中,App.js 组件维护了一个名为 toggled 的布尔状态:

function App() {  // ...  const [toggled, setToggled] = useState(true); // 全局切换状态  // ...  return (    
{/* ...其他组件 */}
{ activeCategory == 0 ? jobs.map((job) => ) : filtered.map((job) => )}
);}

这个 toggled 状态被传递给每一个 JobBoardComponent。在 JobBoardComponent.js 中,handleClick 函数会更新这个全局的 toggled 状态:

function JobBoardComponent({ toggled, setToggled, job }) {  // ...  const handleClick = event => {    setToggled(!toggled); // 更新全局状态  };  return  (     
{/* ...职位摘要信息 */}
{/* ...职位详细描述 */}
{/* ... */}
)}

当任何一个 JobBoardComponent 被点击时,setToggled(!toggled) 会触发 App.js 中 toggled 状态的更新。由于所有 JobBoardComponent 都订阅了同一个 toggled 状态,并且都根据这个状态来决定 jobdesc div的可见性,因此所有职位详情都会同时显示或隐藏。

解决方案:状态提升与局部控制

为了实现点击单个职位只显示其详情,我们需要采用“状态提升”(Lifting State Up)的模式。核心思想是将决定哪个职位详情应该显示的状态管理权上移到共同的父组件(App.js),然后父组件根据这个状态向每个子组件传递一个指示其自身是否应该显示详情的布尔值。

具体步骤如下:

1. 在父组件 (App.js) 中管理选中项ID

不再使用一个通用的 toggled 布尔值,而是在 App.js 中创建一个新的状态变量,用于存储当前被选中(即详情应显示)的职位ID。

// App.jsimport React, {useState, useEffect} from 'react';// ...其他导入function App() {  const [jobs, setJobs] = useState([]);  // ...其他状态  // 新增状态:用于存储当前被点击的职位ID  const [selectedJobId, setSelectedJobId] = useState(null);   useEffect(() => {    setJobs(jobData);  }, []);  // 处理职位点击事件的函数,更新selectedJobId  const handleJobClick = (id) => {    // 如果点击的是同一个职位,则再次点击时隐藏详情 (切换功能)    setSelectedJobId(prevId => (prevId === id ? null : id));  };  return (    
{/* ...其他组件 */}
{ activeCategory == 0 ? jobs.map((job) => ( )) : filtered.map((job) => ( ))}
);}export default App;

在 App.js 中,我们做了以下改动:

引入 selectedJobId 状态,初始化为 null,表示没有职位被选中。定义 handleJobClick 函数,它接收一个 id 参数,并更新 selectedJobId。这里实现了一个切换逻辑:如果点击的ID与当前 selectedJobId 相同,则将其设为 null(隐藏),否则设为新点击的ID(显示)。在 map 循环中,为每个 JobBoardComponent 传递两个新的 props:onJobClick: 一个回调函数,子组件点击时调用,并传入自己的 job.id。isSelected: 一个布尔值,判断当前循环的 job.id 是否与 selectedJobId 相同。

2. 在子组件 (JobBoardComponent.js) 中响应选中状态

JobBoardComponent 不再管理自己的 toggled 状态,而是接收 isSelected prop 来决定是否显示详情。

// JobBoardComponent.jsimport React from "react"; // 不再需要useState和useEffect来管理toggledfunction JobBoardComponent({ onJobClick, isSelected, job }) { // 接收新的props   const langAndTools = [];   const skill = job.skills;   const tools = job.tools;   if (skill && tools) {      langAndTools.push(...skill);      langAndTools.push(...tools);   }    // 移除useEffect和内部的toggled状态管理   const handleClick = () => {      // 调用父组件传递的onJobClick函数,并传入当前job的id      onJobClick(job.id);    };return  (    // onClick事件现在调用本地的handleClick,它会再调用父组件的onJobClick   
@@##@@

{job.company} {job.fresh && ( New)} {job.featured && (Featured)}

{job.position}

{job.postedAt} · {job.contract} · {job.location}

{/* 根据isSelected prop来条件渲染详情区域 */}

Who We Are:

{job.whoweare}



Job Description:

{job.description}





Apply

{langAndTools ? ( langAndTools.map((langAndTool, index) => ( // 添加index作为key,如果langAndTool本身没有唯一id {langAndTool} )) ) : " " }
)} export default JobBoardComponent;

在 JobBoardComponent.js 中,我们做了以下改动:

移除了 toggled 和 setToggled props,以及相关的 useState 和 useEffect 钩子。接收 onJobClick 和 isSelected 作为 props。handleClick 函数现在调用父组件传递下来的 onJobClick,并把当前 job.id 作为参数传回父组件。jobdesc div 的 className 现在根据 isSelected prop 来动态设置,当 isSelected 为 true 时显示,否则隐藏。

总结与注意事项

通过上述改造,我们成功地将控制单个职位详情显示的状态提升到了共同的父组件 App.js。现在,App.js 作为“单一数据源”来管理哪个职位是当前选中的,并通过 isSelected 属性精确地通知每个 JobBoardComponent 自身是否应该显示详情。

关键概念和注意事项:

状态提升 (Lifting State Up): 这是React中管理共享状态的常见模式。当多个子组件需要访问或修改同一个状态,或者一个子组件的状态需要影响另一个子组件时,通常将状态提升到它们最近的共同父组件中。单一数据源: 确保每个状态都有一个明确的所有者。在这个例子中,selectedJobId 由 App.js 拥有和管理。受控组件: JobBoardComponent 变成了一个“受控组件”,它的行为(是否显示详情)完全由其父组件通过 props (isSelected) 控制。唯一标识符 (Key Prop): 在 map 循环中为每个列表项提供一个稳定的、唯一的 key prop 至关重要,这有助于React高效地更新列表,避免性能问题和潜在的bug。这里我们使用了 job.id。切换逻辑: handleJobClick 中的逻辑 setSelectedJobId(prevId => (prevId === id ? null : id)) 实现了点击同一个职位时可以隐藏详情的功能,提供了更好的用户体验。

这种模式不仅解决了当前问题,也为更复杂的交互和状态管理奠定了坚实的基础,是React开发中非常重要且值得掌握的实践。

{job.company}

以上就是ReactJS教程:如何实现点击单个职位显示详情的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1591214.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
从网页直接保存联系人到手机通讯录:可行性与限制
上一篇 2025年12月23日 06:38:00
CSS布局技巧:图像与多行文本的垂直居中对齐
下一篇 2025年12月23日 06:38:19

相关推荐

  • 快手账号如何实名认证_快手账号实名认证的步骤与要求

    快手账号如何实名认证_快手账号实名认证的步骤与要求快手账号如何实名认证_快手账号实名认证的步骤与要求快手账号如何实名认证_快手账号实名认证的步骤与要求快手账号如何实名认证_快手账号实名认证的步骤与要求

    未完成实名认证将限制快手直播和视频发布功能。个人用户需通过身份证认证并可能配合人脸识别,企业用户则需提交营业执照及完成对公打款验证,审核通过后方可开通权限。 如果您已经注册了快手账号,但发现无法开通直播或发布某些视频,很可能是因为尚未完成实名认证。实名认证是使用快手核心功能的前提,未认证账号将受到多…

    2026年9月24日 用户投稿
    200
  • Android应用中通过下载链接从Firebase Storage下载文件教程

    Android应用中通过下载链接从Firebase Storage下载文件教程Android应用中通过下载链接从Firebase Storage下载文件教程Android应用中通过下载链接从Firebase Storage下载文件教程Android应用中通过下载链接从Firebase Storage下载文件教程

    本教程详细介绍了在Android应用中如何利用文件的下载URL,结合Android DownloadManager将Firebase Storage中的文件下载到用户设备指定目录。内容涵盖必要的运行时权限处理、清单文件配置以及DownloadManager的具体使用方法,旨在帮助开发者实现本地文件存…

    2026年9月24日 用户投稿
    200
  • 163邮箱官网手机免费入口 163免费邮箱移动登录

    163邮箱官网手机免费入口 163免费邮箱移动登录163邮箱官网手机免费入口 163免费邮箱移动登录163邮箱官网手机免费入口 163免费邮箱移动登录163邮箱官网手机免费入口 163免费邮箱移动登录

    163邮箱官网手机免费入口可通过访问mail.163.com自动跳转至移动版,或在应用商店下载“网易邮箱”App登录,支持多账号管理、邮件收发、附件添加、消息推送及多设备同步,并提供登录保护、主题自定义和垃圾邮件过滤等安全与个性化功能。 163邮箱官网手机免费入口在哪里?这是不少网友都关注的,接下来…

    2026年9月24日 用户投稿
    000
  • sublime的session文件是做什么用的_sublime会话文件作用与恢复机制

    sublime的session文件是做什么用的_sublime会话文件作用与恢复机制sublime的session文件是做什么用的_sublime会话文件作用与恢复机制sublime的session文件是做什么用的_sublime会话文件作用与恢复机制sublime的session文件是做什么用的_sublime会话文件作用与恢复机制

    Sublime Text的session文件记录了打开的文件、光标位置、代码折叠状态、窗口布局及未保存内容等信息,位于系统特定目录下的Local文件夹中,以JSON格式存储,通过自动保存机制在重启后恢复编辑状态。 Sublime Text 的 session 文件主要用于保存用户当前编辑环境的状态信…

    2026年9月24日 用户投稿
    000
  • ubuntu如何mount网络驱动器

    在ubuntu中挂载网络驱动器有多种方法,以下是一些常见的方法: 方法一:使用mount命令 确定网络驱动器的地址:例如,如果是Samba共享,地址可能是smb://server/share。如果是NFS共享,地址可能是nfs://server/share。安装必要的软件包:对于Samba共享,安装…

    2026年9月24日
    000
  • Java中双精度浮点数的小数位控制技巧

    Java中双精度浮点数的小数位控制技巧Java中双精度浮点数的小数位控制技巧Java中双精度浮点数的小数位控制技巧Java中双精度浮点数的小数位控制技巧

    本文深入探讨了在Java中有效控制double类型数值小数位数的方法。通过Math.round()函数结合乘除操作,可以实现数值本身的四舍五入并改变其精度;而String.format()则提供了灵活的字符串格式化功能,用于在不修改原始数值的情况下精确控制显示的小数位数。这两种方法分别适用于不同的业…

    2026年9月24日 用户投稿
    000
  • 高质量免费logo设计网站 国产免费logo生成工具推荐

    国产免费Logo设计网站推荐即时设计、DesignEvo、牛人设计等,这些平台提供海量模板、支持中文输入与AI智能生成,具备全中文界面、本土化元素和矢量导出功能,适合零基础用户快速制作高质量Logo。 高质量免费logo设计网站国产免费logo生成工具推荐这是不少网友都关注的接下来由PHP小编为大家…

    2026年9月24日
    200
  • UC浏览器怎么查看和清除LocalStorage数据 UC浏览器LocalStorage数据管理方法

    可通过隐私设置清除或开发者工具查看LocalStorage。①在UC浏览器设置中选择“隐私与安全”→“清除浏览数据”,勾选“Cookie及其他网站数据”即可批量删除LocalStorage;②打开uc://inspect启用开发者工具,通过电脑Chrome远程调试查看具体键值对;③root设备后使用…

    2026年9月24日
    200
  • google浏览器怎么把网页保存为PDF_google浏览器网页保存为PDF方法

    使用Chrome将网页保存为PDF,首先按Ctrl+P进入打印界面,选择“另存为PDF”并调整设置后保存;也可通过F12打开开发者工具,截取指定元素或完整页面截图后转为PDF;还可安装“Save as PDF”等扩展程序实现更高质量的导出。 如果您希望将当前浏览的网页完整保存以便离线查看或分享,Go…

    2026年9月24日
    000
  • windows怎么关闭cortana进程_彻底关闭小娜(cortana)后台进程的方法

    1、可通过任务管理器结束Cortana进程并禁用其启动项;2、修改注册表或组策略可永久关闭;3、重命名系统目录文件夹可阻止其运行。 如果您发现Windows系统中Cortana(小娜)后台进程占用资源或影响系统性能,可能是该服务在后台持续运行。以下是彻底关闭Cortana进程的操作步骤: 本文运行环…

    2026年9月24日
    800
  • 苹果过时产品名单更新,M5 iPad Pro 开箱视频流出

    苹果过时产品名单更新,M5 iPad Pro 开箱视频流出苹果过时产品名单更新,M5 iPad Pro 开箱视频流出苹果过时产品名单更新,M5 iPad Pro 开箱视频流出苹果过时产品名单更新,M5 iPad Pro 开箱视频流出

    日前,苹果已将 iphone 11 pro max 和 apple watch series 3 的所有型号列入“过时产品”(vintage product)行列。 根据苹果的规定,一款产品在停止销售满 5 年后,可能会被归为“过时产品”。不过,这一分类并不会显著影响售后服务——苹果仍会继续为这些设…

    2026年9月24日 用户投稿
    600
  • 德系豪华品牌集体投“华” 是什么让BBA放下了身段?

    德系豪华品牌集体投“华” 是什么让BBA放下了身段?德系豪华品牌集体投“华” 是什么让BBA放下了身段?德系豪华品牌集体投“华” 是什么让BBA放下了身段?德系豪华品牌集体投“华” 是什么让BBA放下了身段?

      【小编科技】当德系豪华车徽章与中国科技基因交融,当国资巨头的生产线接入鸿蒙神经中枢,当售价20万元的汽车装上百万级智驾系统——华为正以”技术赋能者”的姿态重构产业格局,成为名副其实的行业顶流。 ☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 免费无限量使用 Deep…

    2026年9月24日 用户投稿
    500
  • MAC系统怎么开启防火墙_MAC开启防火墙教程

    1、建议在Mac系统中开启防火墙以提升网络安全,可通过“系统设置”中的“网络-防火墙”选项启用;2、高级用户可使用终端命令sudo /usr/libexec/ApplicationFirewall/socketfilterfw –setglobalstate on开启服务;3、启用后可在…

    2026年9月24日
    100
  • VSCode的扩展设置是全局的还是局部的?

    VSCode扩展设置默认全局生效,存储于用户配置文件中,但部分扩展如ESLint、Prettier和Python支持项目级局部配置,通过在项目根目录的.vscode/settings.json文件中定义,可覆盖全局设置;在设置界面中,齿轮图标表示可被工作区覆盖,锁图标表示仅限全局修改,用户可根据需求…

    2026年9月24日
    200
  • PHP如何批量处理图片_PHP实现多张图片自动化处理

    批量处理图片时需循环读取并逐个处理,核心是使用scandir()获取文件列表,通过GD库或Imagick处理图像,每处理完一张用imagedestroy()释放内存以避免内存溢出;为提升效率可分批处理、优化算法、使用多进程或异步队列,并选用Intervention Image等高效第三方库。 批量处…

    2026年9月24日
    100
  • MySQL怎样处理SQL注入风险 参数化查询与特殊字符过滤方案

    MySQL怎样处理SQL注入风险 参数化查询与特殊字符过滤方案MySQL怎样处理SQL注入风险 参数化查询与特殊字符过滤方案MySQL怎样处理SQL注入风险 参数化查询与特殊字符过滤方案MySQL怎样处理SQL注入风险 参数化查询与特殊字符过滤方案

    参数化查询和特殊字符过滤是防止sql注入的有效方法。1. 参数化查询通过预处理语句将sql结构与数据分离,用户输入被视为参数,不会被解释为sql命令;2. 特殊字符过滤通过转义或拒绝单引号、双引号等危险字符来阻止攻击;3. 定期审查mysql安全配置,包括更新版本、限制权限、启用日志、使用防火墙和扫…

    2026年9月24日 用户投稿
    000
  • laravel怎么配置Octane并选择Swoole或RoadRunner_laravel Octane Swoole/RoadRunner配置方法

    Laravel Octane通过Swoole或RoadRunner提升应用性能,需安装扩展包并发布配置文件;选择Swoole需安装PHP扩展并设置driver为’swoole’,启动服务时可加–watch实现热重载;选择RoadRunner则自动安装二进制文件,配…

    2026年9月24日
    100
  • 减少PHP与MySQL数据库通信的延迟

    减少php与mysql数据库通信的延迟可以通过以下策略:1. 优化数据库查询,使用索引提升查询速度;2. 减少数据库连接次数,使用连接池管理连接;3. 查询优化,使用explain分析查询计划;4. 使用缓存,如redis,减少数据库查询次数。这些方法能显著提升应用性能,但需权衡利弊,确保系统稳定性…

    2026年9月24日
    000
  • 讯维解决KVM鼠标不同步

    讯维解决KVM鼠标不同步讯维解决KVM鼠标不同步讯维解决KVM鼠标不同步讯维解决KVM鼠标不同步

    使用网络kvm时,常遇到本地鼠标与远程界面光标位置不一致的问题,即鼠标不同步现象,严重影响操作流畅性。可通过优化鼠标同步设置、更新驱动程序或选用兼容性更强的设备来有效改善。 1、配置运行Windows 2000操作系统的服务器环境 2、调整鼠标相关参数 3、点击开始菜单,进入控制面板,选择“鼠标”进…

    2026年9月24日 用户投稿
    900
  • 如何分析Linux进程内存 pmap内存映射检查方法

    如何分析Linux进程内存 pmap内存映射检查方法如何分析Linux进程内存 pmap内存映射检查方法如何分析Linux进程内存 pmap内存映射检查方法如何分析Linux进程内存 pmap内存映射检查方法

    要分析linux进程的内存,特别是利用pmap工具,核心操作是获取目标进程pid后执行pmap -x 。1. 获取pid可通过ps aux | grep your_process_name;2. 执行pmap -x 命令查看扩展格式信息,包括address、kbytes、rss、dirty、mode…

    2026年9月24日 用户投稿
    200

发表回复

登录后才能评论
关注微信