簡體   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