React中.map函数内元素文本截断:hover仅触发单个元素显隐
解决React列表项悬停时全局切换文本显示的问题
问题出在你使用了一个全局的show状态控制所有列表项的显示/隐藏,导致鼠标悬停时所有项同步响应。要实现仅触发当前悬停元素的效果,需要让每个列表项拥有独立的状态控制逻辑,以下是两种可行方案:
方案1:拆分独立子组件(推荐)
将单个用户名称项封装成独立组件,每个组件维护自己的悬停状态,实现状态隔离:
const { useEffect, useState } = React; // 独立的用户名称组件,自带悬停状态 const UserNameItem = ({ name }) => { const [isHovered, setIsHovered] = useState(false); return ( <h3 onMouseOver={() => setIsHovered(true)} onMouseLeave={() => setIsHovered(false)} > {isHovered ? name : `${name.substring(0, 5)}...`} </h3> ); }; function App() { const [data, setData] = useState([]); useEffect(() => { fetch('https://jsonplaceholder.typicode.com/users') .then((response) => response.json()) .then((res) => setData(res)) .catch((err) => console.log("error", err.message)) }, []) return ( <div className="App"> <header className="App-header"> {data.map((user) => ( <UserNameItem key={user.id} name={user.name} /> ))} </header> </div> ); } ReactDOM.createRoot(document.body).render(<App />);
方案2:通过ID标识当前悬停项(不拆分组件)
如果不想拆分组件,可以在父组件中用状态存储当前悬停的用户ID,通过ID匹配控制单个项的显示:
const { useEffect, useState } = React; function App() { const [data, setData] = useState([]); const [hoveredUserId, setHoveredUserId] = useState(null); useEffect(() => { fetch('https://jsonplaceholder.typicode.com/users') .then((response) => response.json()) .then((res) => setData(res)) .catch((err) => console.log("error", err.message)) }, []) return ( <div className="App"> <header className="App-header"> {data.map((user) => ( <h3 key={user.id} onMouseOver={() => setHoveredUserId(user.id)} onMouseLeave={() => setHoveredUserId(null)} > {hoveredUserId === user.id ? user.name : `${user.name.substring(0, 5)}...`} </h3> ))} </header> </div> ); } ReactDOM.createRoot(document.body).render(<App />);
关键说明
- 方案1更符合React组件化思想,每个UI单元状态独立,代码更易维护扩展;
- 方案2适合简单场景,通过ID精准匹配当前悬停项,避免组件拆分;
- 注意使用
user.id作为列表项的key,而非循环索引,索引作为key在数据变动时可能引发渲染异常。
内容的提问来源于stack exchange,提问作者CrRpTDEV
相关产品推荐
相关产品推荐

