Reactjs 反应:未捕获类型错误:tokenIds.map不是函数
我使用React通过钩子从处于状态的数组生成组件。初始化的数组正在正常工作,但在更新其状态后停止工作:Reactjs 反应:未捕获类型错误:tokenIds.map不是函数,reactjs,react-hooks,Reactjs,React Hooks,我使用React通过钩子从处于状态的数组生成组件。初始化的数组正在正常工作,但在更新其状态后停止工作: export function AiShip(props) { const shipType = props.shipType; const maxShields = Ships[shipType][Stats.shields]; const maxHull = Ships[shipType][Stats.hull]; const squadId = props
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/>
这是错误堆栈:
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);
}
问题在这里,在
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()
克隆数组
请注意,这不会克隆阵列中已存在的项目,当您通过扩展阵列时,它们仍然是上一个阵列中的相同实例
setTokens(...tTokenIds)
您的状态不再成为数组,在排列过程中,每个项目都被提取为单个值。因此,它很可能只会导致数组的第一项成为状态,其余项被忽略,因此map
不再可能
您需要将数组扩展到一个新数组中,即[…tTokenIds]
,或者您可以使用tTokenIds.slice()
克隆数组
请注意,这不会克隆阵列中已经存在的项,它们仍然是前一个阵列中的相同实例,这很有趣M谢谢-但是为什么更新后调用的array.isArray(tokenIds)返回true?您能建议一种更新数组的正确方法吗?在使用spread运算符后,它是否返回true?我似乎无法重现这一点。在我的示例中,
Array.isArray(…myArray)
返回false
是,它返回了:tTokenIds.splice(索引,1,值);setTokenId([…TTokenId]);log(“新令牌ID:”);console.log(令牌ID);log(“Is-array:+array.isArray(tokenIds));返回true,控制台中的对象是一个数组,具有更新的值。但你的修改工作如约,非常感谢!这很有趣,谢谢-但是为什么更新后调用的Array.isArray(tokenIds)返回true呢?您能建议一种更新数组的正确方法吗?在使用spread运算符后,它是否返回true?我似乎无法重现这一点。在我的示例中,Array.isArray(…myArray)
返回false
是,它返回了:tTokenIds.splice(索引,1,值);setTokenId([…TTokenId]);log(“新令牌ID:”);console.log(令牌ID);log(“Is-array:+array.isArray(tokenIds));返回true,控制台中的对象是一个数组,具有更新的值。但你的修改工作如约,非常感谢!