React中点击用户时如何单独展示对应用户信息
问题:点击用户名仅展示对应用户信息的实现方案
需求与问题描述
需求:点击用户名时,单独展示该特定用户的信息。
尝试方案:使用handleShow函数切换show状态(false与true互转)控制内容显示隐藏。
遇到的问题:
- 点击任意用户时,三个Card组件的内容都会同时显示;
- 当
show为false时,内容隐藏,但Card的黑色边框依然存在; - 曾尝试给Card的div设置
display: none,但点击用户名时无法触发显示。
附原代码:
// App组件 export default function App() { const [data, setData] = useState([]); const [isLoaded, setIsLoaded] = useState(false); const [show, setShow] = useState(false); const handleShow = () => { setShow((prevShow) => !prevShow); }; useEffect(() => { fetch("https://jsonplaceholder.typicode.com/users") .then((response) => { if (!response.ok) { throw new Error("Data failed to fetch"); } return response.json(); }) .then((data) => { setData(data); setIsLoaded(true); }); }, []); return ( <div className="App"> {isLoaded && ( <> <Users data={data} handleShow={handleShow} /> <Card data={data[0]} show={show} /> <Card data={data[1]} show={show} /> <Card data={data[2]} show={show} /> </> )} </div> ); } // Users组件 const Users = (props) => { const { data, handleShow } = props; return ( <div> <p style={{ cursor: "pointer" }} onClick={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> ); }; export default Users; // Card组件 const Card = (props) => { const { data, show } = props; return ( <div style={{ border: "1px solid black", textAlign: "center" }}> {show && ( <> {" "} <h3>{data?.id}</h3> <h3>{data?.username}</h3> <h3>{data?.email}</h3>{" "} </> )} </div> ); }; export default Card;
解决方案
核心思路:放弃用单一布尔值控制所有Card,改用选中的用户ID精准标记需要展示的对象,实现单个Card的独立控制。
步骤1:修改App组件的状态与事件逻辑
将show状态替换为selectedUserId(初始值为null,表示无选中用户),并让handleShow接收用户ID参数,实现选中/取消选中的切换:
export default function App() { const [data, setData] = useState([]); const [isLoaded, setIsLoaded] = useState(false); // 用选中的用户ID替代布尔值,精准定位展示对象 const [selectedUserId, setSelectedUserId] = useState(null); // 点击时切换选中状态:若当前已选中该用户则取消,否则选中 const handleShow = (userId) => { setSelectedUserId(prevId => prevId === userId ? null : userId); }; useEffect(() => { fetch("https://jsonplaceholder.typicode.com/users") .then((response) => { if (!response.ok) { throw new Error("Data failed to fetch"); } return response.json(); }) .then((data) => { setData(data); setIsLoaded(true); }); }, []); return ( <div className="App"> {isLoaded && ( <> <Users data={data} handleShow={handleShow} /> {/* 给每个Card传入对比条件:当前用户ID是否等于选中ID */} <Card data={data[0]} isVisible={selectedUserId === data[0].id} /> <Card data={data[1]} isVisible={selectedUserId === data[1].id} /> <Card data={data[2]} isVisible={selectedUserId === data[2].id} /> </> )} </div> ); }
步骤2:修改Users组件的点击事件
给每个用户名的点击事件传入对应用户ID,让handleShow明确知道要选中哪个用户:
const Users = (props) => { const { data, handleShow } = props; return ( <div> <p style={{ cursor: "pointer" }} onClick={() => handleShow(data[0].id)}> {data[0].name} </p> <p style={{ cursor: "pointer" }} onClick={() => handleShow(data[1].id)}> {data[1].name} </p> <p style={{ cursor: "pointer" }} onClick={() => handleShow(data[2].id)}> {data[2].name} </p> </div> ); }; export default Users;
步骤3:修改Card组件的渲染逻辑
根据isVisible属性控制整个Card的渲染(包括边框),而非仅控制内部内容:
const Card = (props) => { const { data, isVisible } = props; // 若无需显示,直接返回null,整个Card不渲染,自然无边框残留 if (!isVisible) return null; return ( <div style={{ border: "1px solid black", textAlign: "center" }}> <h3>{data?.id}</h3> <h3>{data?.username}</h3> <h3>{data?.email}</h3> </div> ); }; export default Card;
效果说明
- 点击任意用户名,仅对应用户的Card会显示,其他Card完全隐藏;
- 再次点击已选中的用户名,该Card会隐藏,回到初始状态;
- 未选中用户时,所有Card都不渲染,不会有边框残留。
内容的提问来源于stack exchange,提问作者user18739077
相关产品推荐
相关产品推荐

