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

React实现点击Show Subtasks仅显示当前任务及子任务的方法

实现方法

你现有代码仅控制了子任务的显隐,没有对顶层任务做过滤,调整状态判断和渲染逻辑就能实现需求,核心改动点如下:

  • 统一状态规则:用已有的open状态存当前聚焦的任务标识(优先用任务id,避免重名冲突,现有代码用task.name也能跑通),约定open为null时是默认全展示状态,open匹配到某任务时仅展示该任务和它的子任务
  • 顶层任务加过滤:遍历todos渲染前先判断状态,聚焦状态下只保留匹配open值的任务,其余任务直接不渲染
  • 按钮逻辑对齐:点「Show Subtasks」时把open设为当前任务的标识,点「Hide Subtasks」时把open重置为null回到全展示状态

代码调整示例

首先确认状态和点击方法的定义:

// open初始值设为null,代表默认展示所有任务
const [open, setOpen] = useState(null);

const openClick = (taskIdentifier) => {
  setOpen(taskIdentifier);
};

const closeClick = () => {
  setOpen(null);
};

修改渲染部分的逻辑,核心是给todos遍历增加过滤规则,同时优化按钮显隐、修复原代码的小bug:

return (
    <ListGroup>
        {todos
          // 新增过滤:聚焦状态下仅返回匹配的当前任务,全展示状态返回所有任务
          .filter(task => open === null ? true : task.name === open)
          .map((task, index) => (
            <ListGroup key={task.id || index} >
                <ListGroupItem style={{ textDecoration: completeTask(task) ? 'line-through' : 'none'}} >
                    {index + 1}....{task.name}....( {task.subdata.length} subtasks )
                    {/* 非聚焦状态下才显示展开按钮 */}
                    {open !== task.name && (
                      <Button size='sm' className='mx-2' variant='outline-dark' onClick={() => openClick(task.name)}>
                          Show Subtasks
                      </Button>
                    )}
                    {/* 聚焦状态下才显示收起按钮 */}
                    {open === task.name && (
                      <Button size='sm' variant='outline-secondary' onClick={closeClick}>
                          Hide Subtasks
                      </Button>
                    )}
                </ListGroupItem>
                {task.subdata.filter(child => child.complete === false).map((child, idx) => (
                    <ListGroupItem 
                      style={{ textDecoration: child.complete ? 'line-through' : '', display: open === task.name ? 'block' : 'none' }} 
                      key={child.id || idx} 
                      className='mx-1'
                    >
                        {child.name}
                        {/* 修复原代码未传入父任务标识的问题 */}
                        <Button size='sm' className='mx-5' variant='outline-dark' onClick={() => handleToggle(child.id, task.name)}>
                            <BsCheckLg  />
                        </Button>
                    </ListGroupItem>
                ))}
                <ListGroupItem style={{ fontWeight: 'bold', display: open === task.name ? 'block' : 'none' }} className='mx-2'>
                    Completed Subtasks
                </ListGroupItem>

                {task.subdata.filter(child => child.complete === true).map((child, idx) => (
                    <ListGroupItem 
                      style={{ textDecoration: child.complete ? 'line-through' : '', display: open === task.name ? 'block' : 'none' }} 
                      key={child.id || idx} 
                      className='mx-2'
                    >
                        {child.name}
                        {/* 修复原代码未传入父任务标识的问题 */}
                        <Button size='sm' className='mx-5' variant='outline-dark' onClick={() => unHandleToggle(child.id, task.name)}>
                            <BsXLg  />
                        </Button>
                    </ListGroupItem>
                ))}
            </ListGroup>
        ))}
    </ListGroup>
)

额外优化说明:

  1. 按钮做了条件渲染,避免两种操作按钮同时占位,交互更符合直觉
  2. 所有列表项key优先使用数据自带id,替代数组索引,避免React渲染diff时出现状态错乱
  3. 修复了原代码中子任务操作按钮未传入父任务标识的隐性bug,避免点击时报错

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 17:33:39