React计算器传递useState setter作为回调触发TypeError错误
React计算器中setState setter传入回调时的TypeError问题解决
问题根源
控制台抛出的Uncaught TypeError: param is not a function错误,本质是Key.jsx的handleDataInput函数逻辑顺序错误,没有区分不同类型的回调函数:
- 对于AC、=按钮的回调,需要接收
setEvalData作为参数并调用它; - 对于()按钮的回调,是返回括号字符串的纯函数;
- 当前代码先调用
data.callback(setEvalData),之后又无参数调用data.callback(),导致AC、=的回调接收到undefined作为参数,进而触发调用非函数的错误。
修复方案
调整handleDataInput的逻辑,先判断回调的类型和用途,再执行对应操作,避免无参数调用需要参数的回调:
修改后的Key.jsx代码
export default function Key({ data, setEvalData, leftBracketExist, setLeftBracketExist }) { function handleDataInput(k) { if (!data?.callback) { setEvalData(prev => prev + k) return } // 区分回调类型:函数型回调分两种,字符串型单独处理 if (typeof data.callback === 'function') { // 判断是否是需要setter的回调 const isSetterCallback = ['clear', 'math'].includes(data.type) && data.symbol !== '()' if (isSetterCallback) { // 直接传入setEvalData执行 data.callback(setEvalData) } else if (data.symbol === '()') { // 处理括号回调,生成对应符号并更新状态 const bracket = data.callback(leftBracketExist) setEvalData(prev => prev + bracket) setLeftBracketExist(!leftBracketExist) } } else if (data.callback === 'del') { // 处理删除逻辑 setEvalData(prev => prev.slice(0, -1)) } } return ( <button onClick={() => handleDataInput(data.value)} className={'prevent-select w-full sm:max-w-[90%] aspect-square rounded-[50%] text-xs md:text-sm flex items-center justify-center ' + (data?.bg || ' bg-blue-100')}> {data.symbol} </button> ) }
补充优化(可选)
为了让constants里的回调类型更统一,可以把del的回调也改成函数类型:
// constants.jsx中修改del按钮配置 { symbol: '🠴', callback: (setter) => setter(prev => prev.slice(0, -1)), type: 'del', }
对应的Key.jsx里的del处理逻辑可以合并到setterCallback的判断中。
验证效果
修改后,AC、=按钮的回调只会被传入setEvalData调用一次,不会再出现无参数调用的情况,控制台的TypeError错误会消失,同时所有按钮的功能保持正常。
内容的提问来源于stack exchange,提问作者Steve Carter
相关产品推荐
相关产品推荐

