React: Uncatch TypeError: tokenIds.map 不是一个函数



我正在使用 React 通过钩子从保持状态的数组生成组件。初始化的数组工作没有任何问题,但它在更新其状态后停止工作:

export function AiShip(props) {
const shipType = props.shipType;
const maxShields = Ships[shipType][Stats.shields];
const maxHull = Ships[shipType][Stats.hull];
const squadId = props.squadId;
const [targetPosition, setTargetPosition] = useState([PSN.FARFRONT]);
const [tokenIds, setTokenIds] = useState([3, 4]); //todo remove initial values
function handleTokenIdChange(value, index) {
const tTokenIds = tokenIds;
tTokenIds.splice(index, 1, value);
setTokenIds(...tTokenIds);
};

return (
<div>
<h1>{Ships[props.shipType][Stats.name]}</h1>
<div className="row">
<div className="col-6">
<ShipStats shipType={shipType}/>
<div className="row ">
<div className="col-4">
<h3>ID:</h3>
</div>
<div className="col-4">
<h3>Shields:</h3>
</div>
<div className="col-4">
<h3>Hull:</h3>
</div>
</div>
{
tokenIds.map( (tokenId) =>
<ShipVariables key={tokenIds.indexOf(tokenId)} maxShields={maxShields} maxHull={maxHull}
tokenIdIndex={tokenIds.indexOf(tokenId)}
handleTokenIdChange={handleTokenIdChange}/>)
}
<br/>

状态通过 handleTokenIdChange 函数更新。生成的数组仍然是一个数组(我通过 Array.isArray 函数进行了检查(。触发状态更新的代码如下:

<div className="col-4">
<Select options={idOptions} onChange={e => props.handleTokenIdChange(e.value, props.tokenIdIndex)}/>
</div>

我知道通常问题是变量不是数组,而是例如对象 - 但这里似乎并非如此。结果仍然是一个存储数字的数组。选择允许用户选择以下值之一:

const idOptions = [
{value: 0, label: 0},
{value: 1, label: 1},
{value: 2, label: 2},
{value: 3, label: 3},
{value: 4, label: 4},
{value: 5, label: 5},
{value: 6, label: 6},
{value: 7, label: 7},
{value: 8, label: 8},
{value: 9, label: 9},
];

这是错误堆栈:

AiShip.js:49 Uncaught TypeError: tokenIds.map is not a function
at AiShip (AiShip.js:49)
at renderWithHooks (react-dom.development.js:16260)
at updateFunctionComponent (react-dom.development.js:18347)
at beginWork$1 (react-dom.development.js:20176)
at HTMLUnknownElement.callCallback (react-dom.development.js:336)
at Object.invokeGuardedCallbackDev (react-dom.development.js:385)
at invokeGuardedCallback (react-dom.development.js:440)
at beginWork$$1 (react-dom.development.js:25780)
at performUnitOfWork (react-dom.development.js:24698)
at workLoopSync (react-dom.development.js:24671)
at performSyncWorkOnRoot (react-dom.development.js:24270)
at react-dom.development.js:12199
at unstable_runWithPriority (scheduler.development.js:697)
at runWithPriority$2 (react-dom.development.js:12149)
at flushSyncCallbackQueueImpl (react-dom.development.js:12194)
at flushSyncCallbackQueue (react-dom.development.js:12182)
at discreteUpdates$1 (react-dom.development.js:24423)
at discreteUpdates (react-dom.development.js:1438)
at dispatchDiscreteEvent (react-dom.development.js:5881)
```

问题出在这里,在handleTokenIdChange函数中:

setTokenIds(...tTokenIds);

tTokenIds是一个数组,但...tTokenIds不是:

let myArray = [1,2,3]
console.log(...myArray) // 1 2 3

所以你不能在上面使用.map

溶液

鉴于上下文,我假设您尝试使用解构来创建数组的副本。与其做...tTokenIds,不如使用[...tTokenIds]

let myArray = [1,2,3]
console.log([...myArray]) // [1, 2, 3]

您还可以使用Array.prototype.slice()创建数组的副本:

console.log(myArray.slice()) // [1, 2, 3]

重要须知

请注意,在对状态对象进行任何修改之前创建状态对象的副本是一种更好的做法:

function handleTokenIdChange(value, index) {
const tTokenIds = [...tokenIds];
tTokenIds.splice(index, 1, value);
setTokenIds(tTokenIds);
}

当您通过以下方式传播数组时

setTokens(...tTokenIds)

您的状态不再变成一个数组,每个项目在点差期间被提取为单个值。因此,它很可能只会导致数组的第一项成为状态,而其余项被忽略,因此map不再可能。

您需要将数组分散到一个新数组中,即[...tTokenIds],或者你可以只使用tTokenIds.slice()来克隆数组。

请注意,这不会克隆数组中已有的项目,它们仍将是前一个数组中的相同实例

相关内容

  • 没有找到相关文章

最新更新