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

React中点击P按钮如何实现列表项单独显示Present按钮

问题:点击列表项的P按钮后所有项都显示Present按钮,如何修正?

我是MERN新手,希望实现点击列表中的P按钮后,仅在点击的列表项中显示Present按钮,同时隐藏该列表项的P和A按钮。但当前点击P按钮后,所有列表项都会显示Present按钮,请问该如何修正代码?

原代码:

import React, { useState } from 'react'
import { NavLink } from 'react-router-dom'

const Contracter = () => {
    const [ispresentVisible, setIspresentVisible] = useState(false);
  
    const getmemberid = (id) => { /* 你的逻辑 */ }
    const tomakeabsent = (e, pmId, projectId) => { /* 你的逻辑 */ }

    return (
        <>
            <ol class="list-group list-group-numbered mt-4 ">
                {
                    smember.map((item, i) => (
                        <li class="list-group-item d-flex justify-content-between align-items-start">
                            <div class="ms-2 me-auto">
                                <NavLink onClick={() => { getmemberid(item.PM_id) }} className="text-decoration-none">
                                    <div class="fw-bold">{item.member}</div>
                                </NavLink>
                            </div>
                            <button 
                                data-value1="present" 
                                data-value2="1" 
                                onClick={(e) =>{ setIspresentVisible(!ispresentVisible) }} 
                                className='btn btn-success me-3'
                            >P</button>
                            <button 
                                data-value1="absent" 
                                data-value2="0" 
                                onClick={(e) => { tomakeabsent(e, item.PM_id, item.project_id) }} 
                                className='btn btn-danger '
                            >A</button>
                            {
                                ispresentVisible &&
                                <button className='btn btn-success ms-2'>Present</button>
                            }
                        </li>
                    ))
                }
            </ol>
        </>
    )
}

export default Contracter

解决方案

问题出在你使用了全局布尔状态ispresentVisible,所有列表项共享这个状态,导致点击任意P按钮都会触发所有项的UI同步变化。要实现单个项的独立控制,需要用状态记录当前激活项的唯一标识(比如item.PM_id)。

修改后的代码:

import React, { useState } from 'react'
import { NavLink } from 'react-router-dom'

const Contracter = () => {
    // 用状态存储当前激活项的PM_id,初始值为null表示无激活项
    const [activeItemId, setActiveItemId] = useState(null);
  
    const getmemberid = (id) => { /* 你的逻辑 */ }
    const tomakeabsent = (e, pmId, projectId) => { /* 你的逻辑 */ }

    return (
        <>
            <ol className="list-group list-group-numbered mt-4 ">
                {
                    smember.map((item) => (
                        <li key={item.PM_id} className="list-group-item d-flex justify-content-between align-items-start">
                            <div className="ms-2 me-auto">
                                <NavLink onClick={() => getmemberid(item.PM_id)} className="text-decoration-none">
                                    <div className="fw-bold">{item.member}</div>
                                </NavLink>
                            </div>
                            {/* 非激活项显示P和A按钮 */}
                            {activeItemId !== item.PM_id && (
                                <>
                                    <button 
                                        data-value1="present" 
                                        data-value2="1" 
                                        onClick={() => setActiveItemId(item.PM_id)} 
                                        className='btn btn-success me-3'
                                    >P</button>
                                    <button 
                                        data-value1="absent" 
                                        data-value2="0" 
                                        onClick={(e) => tomakeabsent(e, item.PM_id, item.project_id)} 
                                        className='btn btn-danger '
                                    >A</button>
                                </>
                            )}
                            {/* 激活项显示Present按钮 */}
                            {activeItemId === item.PM_id && (
                                <button className='btn btn-success ms-2'>Present</button>
                            )}
                        </li>
                    ))
                }
            </ol>
        </>
    )
}

export default Contracter

关键修改说明:

  1. 状态重构:把全局布尔状态改为记录激活项PM_id的activeItemId,用null表示无激活项。
  2. UI条件渲染:每个列表项根据自身PM_id与activeItemId的匹配关系,决定显示哪组按钮。
  3. 点击逻辑更新:点击P按钮时,将activeItemId设为当前项的PM_id,实现仅当前项切换UI。
  4. 修复React语法问题:将原代码中的class改为React要求的className,并给列表项添加key属性(列表渲染的必要规范)。

如果需要支持再次点击Present按钮切换回显示P和A按钮,可修改P按钮的点击逻辑:

onClick={() => setActiveItemId(prev => prev === item.PM_id ? null : item.PM_id)}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 18:35:24