繁体   English   中英

React中数组的意外突变

[英]Unexpected mutation of array in React

我刚刚学习编程,并且正在用 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 都读取相同的内容。 也就是内部有 object 的数组,测试键为“test”。 forEach 不会改变原始数组,所有键值,即 id、name 和 ready,都是原语,即 boolean 或字符串。 我这里也没有实现任何异步操作,那为什么我会得到这样的 output? 任何帮助将不胜感激。

下面是整个组件的原始组合供参考(这里的测试密钥也被替换为我需要的实际密钥,但问题仍然存在。

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.testundefined ,第二个返回为"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)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM