如何给useState的setState函数传参?修改代码触发重复渲染报错
嘿,我来帮你搞定这个头疼的React重渲染问题!
错误原因分析
你遇到的这个无限重渲染问题,根源出在按钮的onClick绑定上:
当你写 <button onClick={handleClick(1)}> 的时候,你不是把一个函数传给onClick,而是直接在组件渲染的过程中就执行了handleClick(1)。每次执行这个函数都会调用setCount,而状态更新会触发组件重新渲染,重新渲染时又会再次执行handleClick(1),如此往复就形成了无限循环,React为了保护应用就抛出了"Too many re-renders"的错误。
对比你原来的正确写法:<button onClick={handleClick}> 这里是把handleClick这个函数本身传给了onClick,只有点击按钮的时候才会执行它,所以不会有问题。
修复方案
这里给你几种可行的修复方式,任选其一就行:
方案1:用箭头函数包裹调用
把按钮的onClick改成箭头函数包裹,这样只有点击时才会执行handleClick(1):
<button onClick={() => handleClick(1)}>点击</button>
你的handleClick函数可以保持原来的写法:
const handleClick = (x) => setCount(count + x + 1);
方案2:让handleClick返回一个函数
修改handleClick,让它返回一个函数作为点击回调,这样handleClick(1)的结果就是一个函数,符合onClick的要求:
const handleClick = (x) => () => { setCount(count + x + 1); };
按钮那边就可以保持你原来的写法:
<button onClick={handleClick(1)}>点击</button>
方案3:用函数式更新+useCallback优化(推荐)
另外,建议你使用React的函数式更新来修改状态,这样可以避免闭包带来的旧值问题;如果组件频繁渲染,还可以用useCallback缓存函数:
import { useCallback, useState } from 'react'; // ... const [count, setCount] = useState(0); const handleClick = useCallback((x) => () => { setCount(prevCount => prevCount + x + 1); }, []);
按钮依然是:
<button onClick={handleClick(1)}>点击</button>
总结
记住一个核心规则:React的事件回调(比如onClick)需要接收一个函数引用,而不是函数执行的结果。你之前的写法直接执行了函数,导致渲染时就触发状态更新,进而引发无限循环。
内容的提问来源于stack exchange,提问作者ffs

