React onClick传递方法及参数失效 如何避免箭头函数引发的冗余重渲染
问题根因
- 第一处错误:
onClick={toggle("astma", values.astma)}写法会在组件渲染阶段直接执行toggle函数,而非将其绑定为点击触发的回调函数,这是功能不生效的核心原因。 - 第二处错误:
toggle函数内部解构逻辑错误,const {name, value} = (nameIn, valueIn);中的逗号表达式只会返回最后一个值valueIn,无法正确获取name参数。 - 你提到的内联箭头函数导致重渲染的问题属于过度优化场景:对于绝大多数轻量组件,内联箭头函数的性能损耗可以完全忽略,只有当绑定事件的组件是需要频繁重渲染的复杂列表项时,才需要做针对性优化。
优化解决方案
方案1:利用事件对象读取属性(无额外函数创建)
因为你已经在DOM元素上绑定了name属性,可以直接通过事件对象读取对应属性,不需要手动传参,自然不需要创建内联箭头函数:
function ToggleSwitch() { const [values, setValues] = React.useState({ astma: "off", }); function toggle (e){ const name = e.target.name; setValues(prev => ({ ...prev, [name]: prev[name] === "off" ? "on" : "off" })); }; return ( <div className={`switch ${values.astma}`} onClick={toggle} id="astma" name="astma" /> ); } ReactDOM.render(<ToggleSwitch />, document.getElementById("root"));
配套HTML代码:
<div id="root"></div> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react.production.min.js"></script>
方案2:复杂场景下用useCallback缓存函数
如果是多开关的列表场景,需要避免子组件重渲染,可以配合useCallback和React.memo实现:
const ToggleItem = React.memo(({ name, value, onToggle }) => { return ( <div className={`switch ${value}`} onClick={() => onToggle(name)} name={name} /> ) }) function ToggleSwitch() { const [values, setValues] = React.useState({ astma: "off", fever: "off" }); const toggle = React.useCallback((name) => { setValues(prev => ({ ...prev, [name]: prev[name] === "off" ? "on" : "off" })); }, []); return ( <> <ToggleItem name="astma" value={values.astma} onToggle={toggle} /> <ToggleItem name="fever" value={values.fever} onToggle={toggle} /> </> ); }
这种写法下toggle函数只会在组件首次渲染时创建一次,配合React.memo就不会触发子组件的不必要重渲染。
内容的提问来源于stack exchange,提问作者Mr.Gomer
相关产品推荐
相关产品推荐

