首页 > 解决方案 > 子状态未正确呈现

问题描述

我正在制作一个二十一点应用程序,并且在最初的牌局之后重新渲染牌局时遇到了麻烦。我正在尝试更新 App.js 中的状态并将其传递给 PlayerHand.js 以进行渲染,但子组件并未重新渲染,即使 console.log 显示状态已在 App 中更新。有趣的是,如果我在文本编辑器中按 ctrl-s,PlayerHand.js 将更新,即使我实际上没有更改代码中的任何内容。

应用程序.js

function App() {

  const [lobbyState, updateLobbyState] = useState('');
  const [playerHand, updatePlayerHand] = useState([]);

//code that updates my state
  const hit = () => {
    socket.emit('hit', roomName, function(newCard){ hit
      console.log('old player hand is ' + playerHand);
      var newHand = playerHand;
      newHand.push(newCard);
      updatePlayerHand(newHand);
      console.log('new player hand is ' + playerHand); //this shows a different hand than the first print statement
    });
  }   

//renders initial hands; seems to be working, but included in case it's relevant
socket.on('initialHands', (data) => {
    updateRoomName(data.roomName);
    var newHand = data.playerHand;
    updatePlayerHand(newHand);
    updateOpponentHand(opponentHand.concat([data.opponentFirstCard, 'back'])); 
    updateLobbyState('started');
  })    
  

switch(lobbyState){
        case 'started':
          return (
            <div className="lobby">
              <OpponentHand opponentHand = {opponentHand}/>
              <PlayerHand playerHand = {playerHand} />
              {currentPlayer ? <PlayerActions 
              hit={hit}
              stand={stand}
              /> : <h1> Not your turn </h1>}
              
            </div>
        )
        case 'waiting':
          return (
            <Waiting />
          )
        default:
          return (
            <Home 
            createRoom={createRoom}
            joinRoom={joinRoom}
          />
          )
      }

PlayerHand.js

import React, {useState, useEffect} from 'react';
import cards from './exports';
function PlayerHand (props){
    const [hand, updateHand] = useState([]);
    useEffect(() => {
        var newHand = props.playerHand;
        updateHand(newHand);
    }, [props.playerHand]);
    return (
        <div>
            {hand.map((card) => (<img src={cards[card]} alt="card" className="card"/>))}
        </div>
    )
}

export default PlayerHand;

标签: javascriptreactjs

解决方案


尝试:

  const hit = () => {
    socket.emit('hit', roomName, function(newCard){ hit
      console.log('old player hand is ' + playerHand);
      var newHand = [ ...playerHand ]; // <----- ***** THIS *******
      newHand.push(newCard);
      updatePlayerHand(newHand);
      console.log('new player hand is ' + playerHand); //this shows a different hand than the first print statement
    });
  } 

当你这样做时var newHand = playerHand ,你实际上从来没有创建一个新对象,只是一个新的引用。 var newHand = [ ...playerHand ];另一方面(双关语)确实创建了一个新对象,导致状态改变和重新渲染。


推荐阅读