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

React.js如何实现点击列表项切换对应项的上下箭头图标

实现目标

点击列表项时,仅切换当前项的箭头图标:arrow-up和arrow-down来回切换,其余项图标不受影响。

原有代码问题
  • 全局布尔状态open是所有列表项共用的,值变更时所有项都会读取同一个状态,必然出现所有图标同步切换的问题
  • 单独存selectedIndex的写法只记录了最后点击的索引,没有处理「点击同一项时切换状态」的逻辑,无法实现来回切换的效果
修复方案

根据交互需求二选一即可:

方案1:手风琴模式(同一时间最多1个项展开)

同一时间只允许一个项显示向下箭头,点击已展开的项则收起,核心逻辑是判断当前点击项是否已激活,做对应值的切换:

import React, { useState } from "react";
import { ListGroup } from "react-bootstrap";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faAngleUp, faAngleDown } from "@fortawesome/free-solid-svg-icons";

export const defaultListData = [
  { name: "Dapibus ac facilisis in" },
  { name: "Morbi leo risus" },
  { name: "Porta ac consectetur ac" },
  { name: "Porta ac doesfvsaard  asdas" }
];

function UserSettings() {
  // 初始值为null,默认所有项收起
  const [activeIndex, setActiveIndex] = useState(null);

  const handleItemClick = (index) => {
    // 点击已展开的项就设为null收起,否则设为当前索引展开
    setActiveIndex(activeIndex === index ? null : index);
  };

  return (
    <div>
      {defaultListData.map((category, i) => (
        <ListGroup key={category.name} variant="flush">
          <ListGroup.Item
            onClick={() => handleItemClick(i)}
            style={{ display: "flex", gap: "50px" }}
          >
            {category.name}
            <FontAwesomeIcon
              style={{ color: "green", cursor: "pointer" }}
              icon={activeIndex === i ? faAngleDown : faAngleUp}
            />
          </ListGroup.Item>
        </ListGroup>
      ))}
    </div>
  );
}

export default UserSettings;

方案2:独立控制模式(支持多个项同时展开)

如果需要点击多个项时,每个项的箭头状态独立保存、互不影响,就用数组存储每一项的展开状态:

function UserSettings() {
  // 初始化和列表长度一致的状态数组,默认全部为false(收起)
  const [openStatus, setOpenStatus] = useState(
    Array(defaultListData.length).fill(false)
  );

  const handleItemClick = (index) => {
    setOpenStatus(prev => {
      const newStatus = [...prev];
      // 仅翻转当前点击项的状态
      newStatus[index] = !newStatus[index];
      return newStatus;
    })
  };

  return (
    <div>
      {defaultListData.map((category, i) => (
        <ListGroup key={category.name} variant="flush">
          <ListGroup.Item
            onClick={() => handleItemClick(i)}
            style={{ display: "flex", gap: "50px" }}
          >
            {category.name}
            <FontAwesomeIcon
              style={{ color: "green", cursor: "pointer" }}
              // 读取当前项自身的状态判断显示图标
              icon={openStatus[i] ? faAngleDown : faAngleUp}
            />
          </ListGroup.Item>
        </ListGroup>
      ))}
    </div>
  );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 20:42:16