我遇到的问题是,当我传递 setter 函数作为参数时,我得到
Uncaught TypeError: param2 is not a function
。
我正在构建一个反应计算器应用程序。我创建了一个名为 Constants.jsx 的单独文件,其中包含有关计算器应用程序上我想要的所有按钮的数据。它看起来像这样:
export const mathSymbols = [
{
symbol: 'AC',
callback: (param) => param(''), // this is the callback where the console throws an error
type: 'clear',
bg: 'bg-rose-100'
}
]
我想传递setEvalData,它是一个useState setter函数
const [evalData, setEvalData] = useState('')
并将其作为回调函数中的参数传递。
一切正常,但我在控制台中收到错误。
Uncaught TypeError: param2 is not a function
at Object.callback (constants.jsx:5:37)
at handleDataInput (Key.jsx:13:13)
at onClick (Key.jsx:20:28)
at HTMLUnknownElement.callCallback2 (react-dom_client.js?v=aa76ee9e:3672:22)
at Object.invokeGuardedCallbackDev (react-dom_client.js?v=aa76ee9e:3697:24)
at invokeGuardedCallback (react-dom_client.js?v=aa76ee9e:3731:39)
at invokeGuardedCallbackAndCatchFirstError (react-dom_client.js?v=aa76ee9e:3734:33)
at executeDispatch (react-dom_client.js?v=aa76ee9e:7012:11)
at processDispatchQueueItemsInOrder (react-dom_client.js?v=aa76ee9e:7032:15)
at processDispatchQueue (react-dom_client.js?v=aa76ee9e:7041:13)
// constants.jsx
// This is my file that contains data about the buttons
export const mathSymbols = [
{
symbol: 'AC',
callback: (param) => param(''), // this is the callback where the console throws an error
type: 'clear',
bg: 'bg-rose-100'
},
{
symbol: '()',
callback: (bool = true) => bool ? ')' : '(', // this works fine
type: 'math',
bg: 'bg-blue-200'
},
{
symbol: '%',
value: '%',
type: 'math',
bg: 'bg-blue-200'
},
{
symbol: '\u00F7',
value: '/',
type: 'math',
bg: 'bg-blue-200'
},
{
symbol: '\u2A2F',
value: '*',
type: 'math',
bg: 'bg-blue-200'
},
{
symbol: '-',
value: '-',
type: 'math',
bg: 'bg-blue-200'
},
{
symbol: '+',
value: '+',
type: 'math',
bg: 'bg-blue-200'
},
{
symbol: '=',
callback: (param) => param(previousData => eval(previousData)), // this is the callback where the console throws an error
type: 'math',
bg: 'bg-blue-300'
}
]
export const numbers = [
{
symbol: '9',
value: 9,
type: 'number',
},
{
symbol: '8',
value: 8,
type: 'number',
},
{
symbol: '7',
value: 7,
type: 'number',
},
{
symbol: '6',
value: 6,
type: 'number',
},
{
symbol: '5',
value: 5,
type: 'number',
},
{
symbol: '4',
value: 4,
type: 'number',
},
{
symbol: '3',
value: 3,
type: 'number',
},
{
symbol: '2',
value: 2,
type: 'number',
},
{
symbol: '1',
value: 1,
type: 'number',
},
{
symbol: '0',
value: 0,
type: 'number',
},
{
symbol: '.',
value: '.',
type: 'dot',
},
{
symbol: '🠴',
callback: 'del',
type: 'del',
},
]
// Keys.jsx
// this is my calculator button component
export default function Key({ data, setEvalData, leftBracketExist, setLeftBracketExist }) {
function handleDataInput(k) {
// if data does not have a callback property then input previous data in useState + the value from the
// clicked button
if(!data?.callback) {
setEvalData(previousData => previousData + k)
return
}
// if callback exists in data then I am passing setEvalData which is a useState setter function to
// callback
if(data?.callback) {
data.callback(setEvalData)
}
// ignore this
if(data.callback() === '(' || data.callback() === ')') {
setEvalData(previousData => previousData + data.callback(leftBracketExist))
setLeftBracketExist(!leftBracketExist)
}
}
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>
)
}
// KeyPad.jsx
// This is the calculator's keypad containing all the buttons
// here I am importing data from constants.jsx
import { mathSymbols, numbers } from "../utils/constants"
import { Key } from "."
import { useState } from "react"
export default function KeyPad({ setEvalData }) {
const [leftBracketExist, setLeftBracketExist] = useState(false)
return (
<section className='key-pad-grid w-full px-4 py-4'>
<div className="grid w-full gap-1 grid-cols-3">
{mathSymbols.slice(0, 3).map((symbol, i) => (
<Key data={symbol} key={i} setEvalData={setEvalData} leftBracketExist={leftBracketExist} setLeftBracketExist={setLeftBracketExist}/>
))}
</div>
<div className="grid w-full gap-1 grid-cols-1 ml-1">
{mathSymbols.slice(3).map((symbol, i) => (
<Key data={symbol} key={i} setEvalData={setEvalData}/>
))}
</div>
<div className="grid w-full gap-1 grid-cols-3">
{numbers.map((number, i) => (
<Key data={number} key={i} setEvalData={setEvalData}/>
))}
</div>
</section>
)
}
你到底在哪里使用 mathSymbols 回调