Skip to content
Advertisement

React: Props sent by parent are not the same received by child

Basically the title sums it all, I’m sending a prop to a child and comes different. I make a console.log just before rendering of parent and the prop is OK and make a console.log of same prop at the beginning of Child component and it’s different.

This is the parent:

  const Main = () => {
  const carrier = createShip(5);

  // Gameboards setup
  const userPrimaryGrid = createGameboard('primary');
  const userTrackingGrid = createGameboard('tracking');

  userPrimaryGrid.randomPlaceShip(carrier);

  console.log(userPrimaryGrid.array);

  return (
    <div className="main">
      <Gameboard
        type={'primary'}
        board={userPrimaryGrid}
        enemyArray={computerTrackingGrid}
      />
    </div>
  );
};

export default Main;

And this is the child (I removed mostly everything from child because after receiving the prop wrong everything else is wrong, when I use a mock prop it works):

const Gameboard = (props) => {

  console.log(props.board.array);

  return (
    <div className={`gameBoard ${props.type}Board`} onClick={props.onClick}>
      {squaresArray} <== this depends on board.array don't worry
    </div>
  );
};

export default Gameboard;

I have a suspicion it has something to do with the randomPlaceShip method in parent, because what I receive in child is an array different from the parent one but as if it had its own randomPlaceShip (with another result). The randomePlaceShip method is the following:

const randomPlaceShip = (ship) => {
    let direction = '';
    let randomDirection = _.random(0, 1);
    let x = _.random(0, 9);
    let y = _.random(0, 9);

    randomDirection === 0
      ? (direction = 'horizontal')
      : (direction = 'vertical');

    console.log(x, y, direction);

    let position = false;
    while (position === false) {
      if (direction === 'horizontal') {
        if (y > 10 - ship.length || array[x][y] !== false) {
          console.log(`cant place ship in ${x},${y}`);
          randomDirection = _.random(0, 1);
          x = _.random(0, 9);
          y = _.random(0, 9);
          randomDirection === 0
            ? (direction = 'horizontal')
            : (direction = 'vertical');
          console.log(x, y, direction);
        } else {
          for (let i = 0; i < ship.length; i++) {
            ship.hitPoints[i].x = x;
            ship.hitPoints[i].y = i + y;
            array[x][i + y] = ship.hitPoints[i];
            position = true;
          }
        }
      }

      if (direction === 'vertical') {
        if (x > 10 - ship.length || array[x][y] !== false) {
          console.log(`cant place ship in ${x},${y}`);
          randomDirection = _.random(0, 1);
          x = _.random(0, 9);
          y = _.random(0, 9);
          randomDirection === 0
            ? (direction = 'horizontal')
            : (direction = 'vertical');
          console.log(x, y, direction);
        } else {
          for (let i = 0; i < ship.length; i++) {
            ship.hitPoints[i].x = i + x;
            ship.hitPoints[i].y = y;
            array[i + x][y] = ship.hitPoints[i];
            position = true;
          }
        }
      }
    }
    console.log(x, y, direction);
  };

The console.log within the method matches on what I get in parent; however, in the child component which apparently gets another go to the method won’t show me that console.log so I’m not sure if it’s really running the method.

Advertisement

Answer

I managed to solve it, as Linda also commented, by using setState.

This way:

  const [boards, setBoards] = useState({
    userPrimaryGrid: createGameboard('primary'),
    userTrackingGrid: createGameboard('tracking'),
    computerPrimaryGrid: createGameboard('primary'),
    computerTrackingGrid: createGameboard('tracking'),
  });

  const [gameFinished, setGameFinished] = useState(false);

  const [result, setResult] = useState('');

  useEffect(() => {
    fillBoard(boards.userPrimaryGrid);
    fillBoard(boards.computerPrimaryGrid);
    setBoards({
      userPrimaryGrid: boards.userPrimaryGrid,
      userTrackingGrid: boards.userTrackingGrid,
      computerPrimaryGrid: boards.computerPrimaryGrid,
      computerTrackingGrid: boards.computerTrackingGrid,
    });
  }, [
    boards.computerPrimaryGrid,
    boards.computerTrackingGrid,
    boards.userPrimaryGrid,
    boards.userTrackingGrid,
  ]);

In this case the function fillBoard contains the function randomePlaceShip done to all of the five ships required to play.

Advertisement