React中如何切换映射数组内的指定div?
React映射列表中点赞按钮独立控制问题解决方案
问题描述
React项目中通过映射BulletinBoard数组生成多个div,每个div内的点赞按钮点击后会切换所有div的状态,而非仅当前父div。尝试用switch语句实现无效,且状态管理方式繁琐,希望通过按钮的value(对应item的id)来单独控制对应div的显示状态。
问题根源
- 状态变量冗余且独立:每个item对应一个单独的
showDivX状态,不仅维护麻烦,还无法和映射的item动态关联。 - switch语句逻辑错误:
case 1未添加break,会导致代码穿透到case 2,触发多余的状态更新。 - 渲染判断逻辑错误:所有按钮和显示内容的判断都依赖全局的
showDiv或固定的showDiv1,而非当前item对应的状态,导致点击一个按钮所有元素都变化。 - 全局的
likeButton状态:所有按钮的显示/隐藏都依赖同一个状态,点击后所有按钮都会消失。
解决方案
- 统一管理点赞状态:用一个对象存储所有item的点赞状态,键为item的id,值为布尔值(是否已点赞)。
- 简化点击事件:直接通过点击事件获取item的id,更新对应状态,无需switch语句。
- 动态关联状态与item:渲染时根据当前item的id从状态对象中获取对应的值,实现独立控制。
修改后的代码示例
import { useState } from "react"; import { BulletinBoard } from "./BulletinBoard"; import PostLiked from "./PostLiked"; const ReactPost = () => { // 用对象存储每个item的点赞状态,初始所有为false const [likedPosts, setLikedPosts] = useState({}); const handleLike = (itemId) => { // 更新对应item的点赞状态,取反实现切换效果 setLikedPosts(prev => ({ ...prev, [itemId]: !prev[itemId] })); }; return ( <div className="grid"> {BulletinBoard.map((item) => { // 当前item是否已点赞,未设置过则默认false const isLiked = likedPosts[item.id] || false; return ( <div className="grid-item" key={item.id}> <span className="row"> <p>Fråga #{item.id}</p> <h2>{item.question}</h2> </span> <h3>{item.answer}</h3> <div className={`wrapper__${item.id}`}> {/* 未点赞时显示点赞按钮 */} {!isLiked && ( <button className="likebutton" onClick={() => handleLike(item.id)} >点赞</button> )} {/* 已点赞时显示PostLiked组件 */} {isLiked && <PostLiked />} </div> </div> ); })} </div> ); }; export default ReactPost;
代码说明
likedPosts状态对象:通过item的id作为键,记录每个item的点赞状态,初始为空对象,未点赞的item默认取false。handleLike函数:接收item的id,用函数式更新状态,保留原有状态的同时修改对应id的状态值,避免覆盖其他item的状态。- 渲染逻辑:每个item根据自身id从
likedPosts中获取状态,独立控制按钮显示和PostLiked组件的渲染,实现点击仅影响当前父div。
内容的提问来源于stack exchange,提问作者Tova Jertfelt
相关产品推荐
相关产品推荐

