我刚刚学会编程,正在用React编写我的第一个应用程序之一。我遇到了一个意想不到的突变问题,但我找不到根源。这段代码是一个功能组件的一部分,内容如下。
const players = props.gameList[gameIndex].players.map((item, index) => {
const readyPlayer = [];
props.gameList[gameIndex].players.forEach(item => {
readyPlayer.push({
id: item.id,
name: item.name,
ready: item.ready
})
})
console.log(readyPlayer);
readyPlayer[index].test = "test";
console.log(readyPlayer);
return (
<li key={item.id}>
{/* not relevant to the question */}
</li>
)
})
现在的问题是,readyPlayer似乎在它应该被突变之前就被突变了。两个console.log的读取结果都是一样的。forEach并没有突变原始数组,所有的键值,即id、name和ready,都是布尔或字符串的基元。我在这里也没有实现任何异步操作,为什么会得到这样的输出?如果有任何帮助,将非常感谢。
下面是整个组件的原始组成,供参考(这里也将测试键替换成了我需要的实际键,但无论如何,问题依然存在。
import React from 'react';
import { Link } from 'react-router-dom';
import PropTypes from 'prop-types';
// import styles from './Lobby.module.css';
const Lobby = ( props ) => {
const gameIndex = props.gameList.findIndex(item => item.id === props.current.id);
const isHost = props.gameList[gameIndex].hostId === props.user.uid;
const players = props.gameList[gameIndex].players.map((item, index) => {
const isPlayer = item.id === props.user.uid;
const withoutPlayer = [...props.gameList[gameIndex].players];
withoutPlayer.splice(index, 1);
const readyPlayer = [];
props.gameList[gameIndex].players.forEach(item => {
readyPlayer.push({
id: item.id,
name: item.name,
ready: item.ready
})
})
const isReady = readyPlayer[index].ready;
console.log(readyPlayer);
console.log(!isReady);
readyPlayer[index].ready = !isReady;
console.log(readyPlayer);
return (
<li key={item.id}>
{isHost && index !== 0 && <button onClick={() => props.updatePlayers(props.gameList[gameIndex].id, withoutPlayer)}>Kick Player</button>}
<p>{item.name}</p>
{isPlayer && <button onClick={() =>props.updatePlayers(props.gameList[gameIndex].id, readyPlayer)}>Ready</button>}
</li>
)
})
let showStart = props.gameList[gameIndex].players.length >= 2;
props.gameList[gameIndex].players.forEach(item => {
if (item.ready === false) {
showStart = false;
}
})
console.log(showStart);
return (
<main>
<div>
{showStart && <Link to="/gameboard" onClick={props.start}>Start Game</Link>}
<Link to="/main-menu">Go back to Main Menu</Link>
</div>
<div>
<h3>Players: {props.gameList[gameIndex].players.length}/4</h3>
{players}
</div>
</main>
);
}
Lobby.propTypes = {
start: PropTypes.func.isRequired,
current: PropTypes.object.isRequired,
gameList: PropTypes.array.isRequired,
updatePlayers: PropTypes.func.isRequired,
user: PropTypes.object.isRequired
}
export default Lobby;
注:我确实做到了让组件真正做到了它应该做的事情,但上述意外的突变依然存在,对我来说依然是个谜。
我已经使用你提供的代码片段创建了一个基本的工作示例。两个 console.log
语句在这里返回不同的值。第一个语句返回的是 readyPlayer.test
作为 undefined
第二项为 "test"
. 你确定这个问题发生在你的代码片段中吗?还是我遗漏了什么?
(注意:这个答案应该是一个注释,但我无法在注释中创建一个代码片段。)
const players = [
{
id: 0,
name: "John",
ready: false,
},
{
id: 1,
name: "Jack",
ready: false,
},
{
id: 2,
name: "Eric",
ready: false
}
];
players.map((player, index) => {
const readyPlayer = [];
players.forEach((item)=> {
readyPlayer.push({
id: item.id,
name: item.name,
ready: item.ready
});
});
// console.log(`${index}:${readyPlayer[index].test}`);
readyPlayer[index].test = "test";
// console.log(`${index}:${readyPlayer[index].test}`);
});
console.log(players)