如何在循环中使用useState实现Next.js专辑多选勾选功能?
实现Next.js专辑多选的勾选状态切换功能
核心修改思路
你需要用React的useState Hook来追踪选中的专辑状态,而非普通JavaScript对象——普通对象的变化不会触发组件重新渲染,自然无法更新勾选标记的显示状态。
完整修改代码
import Image from "next/image"; import { Card, CardActionArea } from "@mui/material"; import { useState } from "react"; import { container, card } from "../styles/forms.module.css"; import album from "../public/album.json"; export default function Album() { // 用useState管理选中专辑的状态,键为专辑ID,值为true表示选中 const [selectedAlbums, setSelectedAlbums] = useState({}); // 切换专辑选中状态的函数 function toggleAlbumSelection(albumId) { setSelectedAlbums(prevState => { // 基于上一次的状态更新,避免异步状态更新的问题 if (prevState[albumId]) { // 已选中,移除该专辑 const newState = { ...prevState }; delete newState[albumId]; return newState; } else { // 未选中,添加该专辑 return { ...prevState, [albumId]: true }; } }); } return ( <div className={container}> {Object.keys(album.albums.items).map((key) => { const currentAlbum = album.albums.items[key]; const isSelected = !!selectedAlbums[currentAlbum.id]; return ( <Card key={currentAlbum.id} className={card} style={{ position: 'relative' }}> <CardActionArea onClick={() => toggleAlbumSelection(currentAlbum.id)}> <Image alt={currentAlbum.artists[0].name} width="100%" height="100%" src={currentAlbum.images[1].url} /> {/* 仅当专辑选中时显示勾选标记 */} {isSelected && ( <div style={{ position: 'absolute', top: 12, right: 12, backgroundColor: 'rgba(255,255,255,0.9)', borderRadius: '50%', width: 36, height: 36, display: 'flex', alignItems: 'center', justifyContent: 'center', boxShadow: '0 2px 4px rgba(0,0,0,0.2)' }}> <span style={{ fontSize: 20, color: '#1976d2' }}>✓</span> </div> )} </CardActionArea> </Card> ); })} </div> ); }
关键说明
- 状态管理:
selectedAlbums是存储选中专辑ID的对象,React会监听该状态变化,自动触发组件重新渲染。 - 状态更新逻辑:使用
setSelectedAlbums的回调函数更新状态,确保每次更新都基于最新的状态值,避免异步更新导致的错误。 - 列表渲染规范:给每个
Card添加唯一的key(使用专辑ID),符合React列表渲染要求,避免性能问题和警告。 - 勾选标记控制:通过
isSelected变量判断当前专辑是否被选中,条件渲染勾选标记,实现点击切换显示/隐藏的效果。
内容的提问来源于stack exchange,提问作者Louis
相关产品推荐
相关产品推荐

