React使用Material UI useStyles实现卡片选中时其余卡片类未移除问题
问题根因
你当前的选中状态selected定义在单个Occasion卡片组件内部,每一张渲染出来的卡片都持有独立的局部状态,互相之间状态不共享。点击卡片时只会更新当前被点击卡片自身的selected值,其他卡片的状态没有任何变化,因此不会主动移除自身的选中样式。
修复方案
把选中状态向上提升到所有卡片的公共父组件中,父组件统一维护当前选中的id,再将选中值、选中处理函数通过props传递给每个Occasion子组件即可。
父组件示例代码
import { useState } from 'react'; import Grid from '@mui/material/Grid'; import { Occasion } from './Occasion'; export const OccasionList = () => { // 父组件统一维护全局选中状态 const [selectedId, setSelectedId] = useState<string>(''); // 你的卡片数据源,根据实际业务调整 const occasionList = [ {id: '1', name: '场合1'}, {id: '2', name: '场合2'}, {id: '3', name: '场合3'}, ] return ( <Grid container spacing={2}> {occasionList.map(occasion => ( <Occasion key={occasion.id} occasion={occasion} selectedId={selectedId} onSelect={setSelectedId} /> ))} </Grid> ) }
子组件调整后代码
import { useState } from 'react'; import { makeStyles, createStyles, Theme } from '@mui/styles'; import Grid from '@mui/material/Grid'; import Card from '@mui/material/Card'; import CardActionArea from '@mui/material/CardActionArea'; import Typography from '@mui/material/Typography'; // 引入你实际用的Icon组件 import IconRounded from '@mui/icons-material/YourIcon'; const useStyles = makeStyles((theme: Theme) => createStyles({ cardSelected: { backgroundColor: theme.palette.action.selected }, actionArea: { // 补全你原本的样式 }, iconItem: { // 补全你原本的样式 } }) ); // 定义子组件入参 interface OccasionProps { occasion: { id: string; name: string; }; selectedId: string; onSelect: (id: string) => void; } export const Occasion = ({ occasion, selectedId, onSelect }: OccasionProps): JSX.Element => { const classes = useStyles(); const handleSelect = () => { onSelect(occasion.id); } return ( <Grid item xs={12} sm={6} md={3}> <CardActionArea className={classes.actionArea} onClick={handleSelect}> <Card className={ selectedId === occasion.id ? classes.cardSelected : '' }> <IconRounded className={classes.iconItem} color="secondary" /> <Typography variant="h5" component="h3">{ occasion.name } </Typography> </Card> </CardActionArea> </Grid> ); }
调整后所有卡片的选中状态由父组件统一管理,每次选中新卡片时全局selectedId更新,所有子组件都会自动匹配自身id与选中id,对应新增或移除选中样式。同时也省去了读取DOM属性data-option的操作,直接通过props取值更安全稳定。
内容的提问来源于stack exchange,提问作者Rob Irvin
相关产品推荐
相关产品推荐

