React Typescript遍历数组渲染按钮如何实现单次仅选中单个按钮?
单选功能实现方案
你当前的代码所有按钮共用同一个布尔类型的选中状态isClicked,因此任意按钮触发状态变更后,所有按钮的clicked属性都会同步更新,导致点击一个所有按钮都被标记为选中,按以下步骤修改即可实现单选逻辑:
具体修改步骤
1. 修改状态定义
将原来存储布尔值的状态,改为存储当前选中按钮的ID,初始值设为null表示初始无选中项:
// 原代码 // const [isClicked, setClicked] = useState(false); // 修改后 const [activeId, setActiveId] = useState<number | null>(null);
2. 修改点击回调函数
给回调函数新增按钮ID入参,点击时直接将状态更新为当前点击的按钮ID,也可以增加判断实现点击已选中按钮时取消选中的效果:
// 原代码 // const clickMe = (): void => { // console.log("say hello new"); // setClicked(!isClicked); // }; // 修改后 const clickMe = (id: number): void => { console.log("say hello new"); // 支持点击已选中按钮取消选中,不需要的话直接写setActiveId(id)即可 setActiveId(prevActiveId => prevActiveId === id ? null : id); };
3. 修改列表渲染逻辑
渲染每个BigButton时,将当前按钮的ID传入点击回调,同时判断当前按钮ID是否等于状态中存储的激活ID,作为clicked属性的传入值:
// 原代码 // buttonContents.forEach((item) => { // buttonContentsList.push( // <BigButton // onClick={() => { // clickMe(); // }} // Title={item.Title} // Description={item.Description} // clicked={isClicked} // ></BigButton> // ); // }); // 修改后 buttonContents.forEach((item) => { buttonContentsList.push( <BigButton onClick={() => { clickMe(item.id); }} Title={item.Title} Description={item.Description} clicked={item.id === activeId} ></BigButton> ); });
可选优化
React中渲染列表更推荐使用map方法,无需单独声明空数组push,写法更简洁,同时注意给列表项加唯一key属性避免控制台警告,优化后的完整代码如下:
const Sandbox = () => { const [activeId, setActiveId] = useState<number | null>(null); const clickMe = (id: number): void => { console.log("say hello new"); setActiveId(prev => prev === id ? null : id); }; const buttonContents = [ { id: 1, Title: "One", Description: "First" }, { id: 2, Title: "Two", Description: "Second" }, { id: 3, Title: "Three", Description: "Third" }, { id: 4, Title: "Four", Description: "Fourth" }, ]; return <> {buttonContents.map(item => ( <BigButton key={item.id} onClick={() => clickMe(item.id)} Title={item.Title} Description={item.Description} clicked={item.id === activeId} /> ))} </>; }; export default Sandbox;
内容的提问来源于stack exchange,提问作者joekevinrayan96
相关产品推荐
相关产品推荐

