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

React循环渲染时如何基于索引为点击选中项单独应用CSS样式

问题原因

你当前使用全局单一布尔值isBarOpen作为所有列表项的样式判断依据,所有列表项共享同一个状态,点击任意项修改状态后,所有项都会读取到同一个激活值,因此会同步套用激活样式。

实现方案

核心逻辑是将「全局布尔状态」替换为「存储当前选中项标识的状态」,渲染每一项时单独判断当前项是否为选中项,单独生成对应样式:

  • 初始化状态存储选中项的索引/唯一业务ID,默认值设为null表示初始无选中项
  • 遍历渲染列表时,逐次判断当前项的标识是否与状态中存储的选中标识一致,将判断结果传入样式生成方法
  • 点击列表项时,将当前项的标识更新到状态中,即可实现仅选中项套用激活样式
修改后代码

组件状态与渲染逻辑

// 替换原有的isBarOpen布尔状态,存储当前选中的票务索引,默认无选中
const [selectedTicketIndex, setSelectedTicketIndex] = useState(null);

// 列表遍历渲染(替换原有的map逻辑)
{ticketList.map((ticket, i) => {
  // 单独判断当前项是否为选中项,生成当前项专属样式
  const isBarOpen = selectedTicketIndex === i;
  const classes = getStyles.new_ticketSearch({ isBarOpen })();

  return (
    <Box
      className={classes.bookingTicketContainer}
      onClick={() => {
        handleOnSelectTicket(i);
        // 点击同一项可取消选中,若需要点击后固定选中不取消,直接写setSelectedTicketIndex(i)即可
        setSelectedTicketIndex(selectedTicketIndex === i ? null : i);
      }}
    >
      <Box className={classes.bookingBar}>
        <Box className={classes.bookingSubBox}>
          <Box className={classes.barInfoboxN1}>
            <Typography className={classes.durationDetails}>{ticket.ticketsOverview[1]}</Typography>
          </Box>
          <Box className={classes.barInfoBoxN2}>
            <Typography className={classes.changesDetails}>N/A</Typography>
          </Box>
          <Box className={classes.barInfoboxN3}>
            <Typography className={classes.transportModeDetails}>
              {ticket.ticketsOverview[8]}
            </Typography>
          </Box>
          <Box className={classes.barInfoboxN4}>
            <Typography className={classes.priceDetails}>
              {ticket.ticketsOverview[3]} {ticket.ticketsOverview[4]} {ticket.ticketsOverview[5]}
            </Typography>
          </Box>
        </Box>
      </Box>
    </Box>
  )
})}

样式代码

原有JSS样式逻辑无需修改,会根据每一项单独传入的isBarOpen值自动生成对应样式:

bookingBar: {
  display: "flex",
  width: 751,
  height: 76,
  background: !isBarOpen ? theme.palette.common.white : theme.palette.primary[500],
  color: isBarOpen && theme.palette.common.white,
  boxShadow: "0px 2px 2px 1px rgba(0, 0, 0, 0.12), 0px 2px 6px 2px rgba(0, 0, 0, 0.08)",
  borderRadius: 5,
},
优化提示
  • 若列表数据存在动态增删、排序的场景,不要用索引作为选中标识,优先用票务数据本身的唯一ID(比如ticketId)存储选中状态,避免索引错位导致样式异常
  • 若需要支持多选,可将状态改为数组类型,存储所有选中项的标识,判断选中时用selectedIdList.includes(currentItemId)即可

内容的提问来源于stack exchange,提问作者Sudhir

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 15:12:21