You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 13:37:05