如何结合useState钩子正确实现React图标点击切换功能
问题原因
你代码里的问题集中在三点,你自己标注的那行<img>标签的写法就是核心错误之一:
react-icons导出的是封装好的React SVG组件,不是静态图片路径,不能赋值给<img>标签的src属性渲染,直接作为组件引用即可- 维护了两个冗余状态:控制选中态的
icon和存当前图标的click,完全没必要,多状态同步很容易出bug,而且事件回调里直接读取当前icon值判断会遇到React闭包陷阱,拿到的不是最新状态 - 点击次数的展示逻辑错误:你把存了图标组件的
click变量插到了文案里,根本统计不了点击次数
修正后的可运行代码
import React, { useState } from 'react' import './App.css' import { GrCheckbox as Box } from 'react-icons/gr' import { GrCheckboxSelected as BoxChecked } from 'react-icons/gr' export default function App() { // 单个布尔状态控制选中/未选中状态即可 const [isChecked, setIsChecked] = useState(false); // 单独维护点击计数状态 const [clickCount, setClickCount] = useState(0); function handleClick() { // 用函数式更新避开闭包问题,保证拿到的是最新状态 setIsChecked(prev => !prev); setClickCount(prev => prev + 1); } return ( <div className="App"> {/* 直接条件渲染对应图标组件,加手型光标符合可点击交互的视觉提示 */} <span onClick={handleClick} style={{cursor: 'pointer', fontSize: '24px'}}> {isChecked ? <BoxChecked /> : <Box />} </span> <p>Clicked {clickCount} times</p> </div> ); }
关键改动说明
- 删掉了冗余的存储图标组件的状态,直接根据选中态布尔值做条件渲染,从根源上避免多状态不同步的问题
- 替换了错误的
<img>标签写法,直接渲染react-icons导出的组件,给外层绑定点击事件即可 - 状态更新统一用函数式写法,规避React合成事件里的状态闭包问题
- 单独拆分点击计数状态,修正原来把图标组件插入计数文案的错误
小技巧:react-icons导出的组件本身支持直接传
size、color等属性控制样式,不需要额外套标签就能调整外观,比如<BoxChecked size={24} color="#1677ff" />就可以直接设置图标大小和主题色。
内容的提问来源于stack exchange,提问作者mireumireu
相关产品推荐
相关产品推荐

