You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 02:39:02