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
关键修改说明:
- 状态重构:把全局布尔状态改为记录激活项
PM_id的activeItemId,用null表示无激活项。 - UI条件渲染:每个列表项根据自身
PM_id与activeItemId的匹配关系,决定显示哪组按钮。 - 点击逻辑更新:点击P按钮时,将
activeItemId设为当前项的PM_id,实现仅当前项切换UI。 - 修复React语法问题:将原代码中的
class改为React要求的className,并给列表项添加key属性(列表渲染的必要规范)。
如果需要支持再次点击Present按钮切换回显示P和A按钮,可修改P按钮的点击逻辑:
onClick={() => setActiveItemId(prev => prev === item.PM_id ? null : item.PM_id)}
内容的提问来源于stack exchange,提问作者rahul
相关产品推荐
相关产品推荐

