
本教程详细讲解如何在React应用中实现点击用户名时,仅显示对应用户的详细信息,并解决全局显示状态导致的所有卡片同时显示以及隐藏时出现边框的问题。通过引入局部状态管理和优化条件渲染逻辑,我们将构建一个高效且用户体验友好的组件交互方案。
在React开发中,我们经常会遇到需要根据用户交互动态显示或隐藏特定内容的需求。一个常见的场景是,当用户点击列表中的某个条目(例如用户名)时,只显示该条目的详细信息,而其他条目的详情则保持隐藏。然而,不恰当的状态管理和条件渲染方式可能会导致一些问题,比如所有相关内容同时显示/隐藏,或者在内容隐藏时仍然出现不必要的视觉元素(如边框)。
原始代码尝试通过一个全局的 show 状态来控制所有用户详情卡片的显示与隐藏。
// App.js 核心片段
export default function App() {
const [show, setShow] = useState(false); // 全局显示状态
const handleShow = () => { // 切换全局显示状态
setShow((prevShow) => !prevShow);
};
return (
<div className="App">
{isLoaded && (
<>
<Users data={data} handleShow={handleShow} /> {/* Users组件传递同一个handleShow */}
<Card data={data[0]} show={show} /> // 所有Card组件都接收同一个show状态
<Card data={data[1]} show={show} />
<Card data={data[2]} show={show} />
</>
)}
</div>
);
}
// Users.js 核心片段
const Users = (props) => {
const { data, handleShow } = props;
return (
<div>
<p style={{ cursor: "pointer" }} onClick={handleShow}> // 所有用户点击都触发同一个handleShow
{data[0].name}
</p>
<p style={{ cursor: "pointer" }} onClick={handleShow}>
{data[1].name}
</p>
<p style={{ cursor: "pointer" }} onClick={handleShow}>
{data[2].name}
</p>
</div>
);
};
// Card.js 核心片段
const Card = (props) => {
const { data, show } = props;
return (
<div style={{ border: "1px solid black", textAlign: "center" }}> // 即使不显示内容,div和边框依然存在
{show && (
<>
{" "}
<h3>{data?.id}</h3>
<h3>{data?.username}</h3>
<h3>{data?.email}</h3>{" "}
</>
)}
</div>
);
};从上述代码中,我们可以发现几个关键问题:
要解决这些问题,我们需要引入更精细的状态管理策略,并优化组件的条件渲染逻辑。
在 App 组件中,我们需要一个状态来记录当前应该显示哪个用户的详细信息。我们可以使用 selectedUserId 来存储被选中用户的ID。
// App.js
import React, { useState, useEffect } from "react";
// 引入 Users 和 Card 组件
// import Users from "./Users"; // 假设在同一目录
// import Card from "./Card"; // 假设在同一目录
export default function App() {
const [data, setData] = useState([]);
const [isLoaded, setIsLoaded] = useState(false);
const [selectedUserId, setSelectedUserId] = useState(null); // 新增:存储当前选中用户的ID
useEffect(() => {
fetch("https://jsonplaceholder.typicode.com/users")
.then((response) => {
if (!response.ok) {
throw new Error("数据获取失败");
}
return response.json();
})
.then((usersData) => { // 将变量名改为usersData避免与组件的data props混淆
setData(usersData);
setIsLoaded(true);
})
.catch((error) => {
console.error("获取用户数据时发生错误:", error);
setIsLoaded(true); // 即使失败也标记为加载完成,防止无限加载状态
});
}, []);
// 新增:处理用户点击事件,更新selectedUserId
const handleUserClick = (userId) => {
// 如果点击的是当前已选中的用户,则取消选中(隐藏)
// 否则,选中新用户(显示)
setSelectedUserId((prevSelectedUserId) =>
prevSelectedUserId === userId ? null : userId
);
};
return (
<div className="App">
{isLoaded ? ( // 使用三元运算符处理加载状态
<>
{/* 将 handleUserClick 传递给 Users 组件 */}
<Users users={data} onUserSelect={handleUserClick} />
{/* 动态渲染所有用户的Card组件 */}
{data.map((user) => (
<Card
key={user.id} // 列表渲染时务必添加key
userData={user}
selectedUserId={selectedUserId} // 传递当前选中ID
/>
))}
</>
) : (
<div>加载中...</div> // 加载状态提示
)}
</div>
);
}Users 组件现在需要遍历所有用户并为每个用户渲染一个可点击的名称。点击时,它应该调用父组件传递下来的回调函数,并传入当前用户的ID。
Android服务Service_详解 WORD版
本文档主要讲述的是Android服务Service_详解;服务(Service)是Android系统中4个应用程序组件之一(其他的组件详见3.2节的内容)。服务主要用于两个目的:后台运行和跨进程访问。通过启动一个服务,可以在不显示界面的前提下在后台运行指定的任务,这样可以不影响用户做其他事情。通过AIDL服务可以实现不同进程之间的通信,这也是服务的重要用途之一。希望本文档会给有需要的朋友带来帮助;感兴趣的朋友可以过来看看
0
查看详情
// Users.js
import React from "react";
const Users = (props) => {
const { users, onUserSelect } = props; // 接收 users 和 onUserSelect
return (
<div>
<h2>用户列表</h2>
{users.map((user) => ( // 遍历所有用户
<p
key={user.id} // 列表渲染时务必添加key
style={{ cursor: "pointer", fontWeight: 'bold' }}
onClick={() => onUserSelect(user.id)} // 点击时调用onUserSelect并传入当前用户ID
>
{user.name}
</p>
))}
</div>
);
};
export default Users;Card 组件现在将根据传入的 userData.id 是否与 selectedUserId 匹配来决定是否渲染其内容。关键在于,如果卡片不应该显示,它应该 完全不渲染任何DOM元素,而不是仅仅隐藏内部内容。
// Card.js
import React from "react";
const Card = (props) => {
const { userData, selectedUserId } = props; // 接收 userData 和 selectedUserId
// 判断当前卡片是否应该显示
const shouldShow = userData.id === selectedUserId;
// 如果不应该显示,则直接返回一个空片段,不渲染任何DOM元素
if (!shouldShow) {
return <></>; // 或者 return null;
}
// 如果应该显示,则渲染用户详情
return (
<div
style={{
border: "1px solid black",
textAlign: "center",
margin: "10px 0",
padding: "10px",
backgroundColor: "#f9f9f9",
}}
>
<h3>ID: {userData?.id}</h3>
<h3>用户名: {userData?.username}</h3>
<h3>邮箱: {userData?.email}</h3>
</div>
);
};
export default Card;将上述修改整合到 App.js、Users.js 和 Card.js 中,即可实现所需功能。
App.js
import React, { useState, useEffect } from "react";
import Users from "./Users";
import Card from "./Card";
import "./App.css"; // 假设有App.css文件,或者直接使用内联样式
export default function App() {
const [data, setData] = useState([]);
const [isLoaded, setIsLoaded] = useState(false);
const [selectedUserId, setSelectedUserId] = useState(null);
useEffect(() => {
fetch("https://jsonplaceholder.typicode.com/users")
.then((response) => {
if (!response.ok) {
throw new Error("数据获取失败");
}
return response.json();
})
.then((usersData) => {
setData(usersData);
setIsLoaded(true);
})
.catch((error) => {
console.error("获取用户数据时发生错误:", error);
setIsLoaded(true);
});
}, []);
const handleUserClick = (userId) => {
setSelectedUserId((prevSelectedUserId) =>
prevSelectedUserId === userId ? null : userId
);
};
return (
<div className="App">
<h1>用户详情展示</h1>
{isLoaded ? (
<>
<Users users={data} onUserSelect={handleUserClick} />
{data.map((user) => (
<Card
key={user.id}
userData={user}
selectedUserId={selectedUserId}
/>
))}
</>
) : (
<div>加载中...</div>
)}
</div>
);
}Users.js
import React from "react";
const Users = (props) => {
const { users, onUserSelect } = props;
return (
<div>
<h2>用户列表</h2>
{users.map((user) => (
<p
key={user.id}
style={{ cursor: "pointer", fontWeight: 'bold', color: '#007bff' }}
onClick={() => onUserSelect(user.id)}
>
{user.name}
</p>
))}
</div>
);
};
export default Users;Card.js
import React from "react";
const Card = (props) => {
const { userData, selectedUserId } = props;
const shouldShow = userData.id === selectedUserId;
if (!shouldShow) {
return <></>;
}
return (
<div
style={{
border: "1px solid #ddd",
borderRadius: "8px",
textAlign: "center",
margin: "15px 0",
padding: "15px",
backgroundColor: "#fefefe",
boxShadow: "0 2px 4px rgba(0,0,0,0.1)",
}}
>
<h3>ID: {userData?.id}</h3>
<h3>用户名: {userData?.username}</h3>
<h3>邮箱: {userData?.email}</h3>
</div>
);
};
export default Card;通过上述优化,我们成功解决了在React中点击用户名时,所有用户详情同时显示以及隐藏时出现边框的问题。核心在于将全局的显示状态替换为针对单个用户ID的选中状态,并结合彻底的条件渲染来精确控制每个 Card 组件的可见性。这种模式在React开发中非常常见且实用,能够帮助我们构建出更具交互性和稳定性的应用。
以上就是React中实现用户详情的按需显示与隐藏的详细内容,更多请关注其它相关文章!
# 用户列表
# 宁波关键词排名如何优化
# 中山企业seo
# 网站建设当选林洁
# 常州网站建设智博
# SEO精华版
# 惠州网站建设过程
# 黑龙江推广网站制作
# 东莞专题网站建设方案
# 肇庆谷歌seo排名
# 台州网站建设信息公示
# 输入框
# 发生错误
# 中非
# 遍历
# 按需
# css
# 而不是
# 的是
# 加载
# 回调
# 点击事件
# 常见问题
# 邮箱
# ai
# 回调函数
# app
# 编码
# json
# js
# react
相关栏目:
【
Google疑问12 】
【
Facebook疑问10 】
【
优化推广96088 】
【
技术知识133117 】
【
IDC资讯59369 】
【
网络运营7196 】
【
IT资讯61894 】
相关推荐:
汽水音乐车机版 汽水音乐车机版官方入口
《花瓣》创建专辑方法
Composer如何使用composer-plugin-api开发自定义插件
C++ cast类型转换总结_C++ reinterpret_cast与const_cast的使用
荣耀Magic7拍照夜景噪点处理_荣耀Magic7相机优化
苹果手机如何清理系统缓存数据 iPhone非越狱清理垃圾文件的技巧【系统优化】
如何取消数字签名
掌握产品代码正则表达式:避免常见陷阱与精确匹配
yandex网页版直接登录 yandex官方入口平台访问方法
悟空浏览器网页版在线工具 悟空浏览器网页版在线平台入口
抖音号显示企业机构号是什么意思?企业机构号申请条件是什么?
C++ virtual析构函数作用_C++基类虚析构函数防止内存泄漏
Golang如何实现HTTP请求重试机制_Golang HTTP请求错误处理策略
Apple Music无故扣费引质疑
J*aScript大数运算_BigInt使用指南
苹果手机怎么合并照片_苹果手机合并多张照片的操作方法
PHP utf8_encode 字符编码转换陷阱与解决方案
Windows 11怎么删除恢复分区_Windows 11使用Diskpart命令强行删除分区
服装短视频如何起号推广?服装短视频起号推广有什么要求?
Sublime怎么快速复制文件路径_Sublime右键菜单增强技巧
抖音官网入口快速访问 抖音网页版账号注册解析
胃动力不足?试试这5个调理方法
解决CSS background 属性中 cover 关键字的常见误用
Golang如何初始化module项目_Golang module init使用说明
如何编写一个符合 composer 规范的 post-install-cmd 脚本?
使用逻辑应用(Logic Apps)自动处理邮件附件中的XML到Excel
银信通自动开通原因揭秘
51漫画网实时入口 51漫画网页版官方免费漫画入口
快手缓存清理方法
荣耀盒子应用管理技巧
《原神》月之一版本新增书籍一览
Yandex无需登录畅游 俄罗斯搜索引擎最新官网指南
VB表达式书写规则解析
《单词速记宝》设置学习计划方法
Excel宏怎么删除_Excel中删除宏的详细操作流程
植物大战僵尸95版游戏版下载_植物大战僵尸95版游戏版安装指南
Golang中的rune与byte类型区别是什么_Golang字符与字节处理详解
excel怎么计算平均值 excel平均函数*ERAGE使用教学
手机耗电快是什么原因 延长手机电池续航时间的设置方法【详解】
顺丰快递怎么查物流_顺丰快递物流信息实时查询操作指南
J*aScript二进制处理_ArrayBuffer与Blob
oppo手机如何通过下拉通知栏截图_oppo手机通知栏快捷截图方法
PHP utf8_encode 字符编码转换疑难解析与最佳实践
房产|直播|视频号怎么认证开通?|直播|需要什么资质?
抖音视频如何添加标题?添加标题有哪些好处?
Sublime Text怎么关闭自动完成_Sublime禁用Auto Complete设置
sublime怎么快速在浏览器中预览HTML_sublime配置View in Browser教程
电脑视频号|直播|如何分享屏幕
海棠阅读登录教程_详细讲解海棠登录操作
汽水音乐官方网站登录入口_汽水音乐网页版进入链接
2025-11-10
运城市盐湖区信雨科技有限公司是一家深耕海外推广领域十年的专业服务商,作为谷歌推广与Facebook广告全球合作伙伴,聚焦外贸企业出海痛点,以数字化营销为核心,提供一站式海外营销解决方案。公司凭借十年行业沉淀与平台官方资源加持,打破传统外贸获客壁垒,助力企业高效开拓全球市场,成为中小企业出海的可靠合作伙伴。