Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

177
Views
Child state not rendering properly

I'm making a blackjack app, and I'm having trouble re-rendering hands after the initial hands. I'm trying to update my state in App.js and pass it to PlayerHand.js to be rendered, but the child component is not re rendering, even though a console.log shows that the state has been updated in App. Interestingly, if I hit ctrl-s in my text editor, PlayerHand.js will update, even if I haven't actually changed anything in the code.

App.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;
about 4 years ago · Juan Pablo Isaza
2 answers
Answer question

0

Try:

  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
    });
  } 

When you do var newHand = playerHand , you are actually never creating a new object, only a new reference. var newHand = [ ...playerHand ]; on the other hand (pun intended) does create a new object which causes state to change and a re-render.

about 4 years ago · Juan Pablo Isaza Report

0

Try updatePlayerHand(playerHand.concat(newCard)).

concat should be used instead of push with setState. I am not sure about useState hook though.

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!