【问题标题】:React: Props sent by parent are not the same received by childReact:父母发送的道具与孩子收到的道具不同
【发布时间】:2021-03-19 14:33:03
【问题描述】:

基本上,标题总结了一切,我正在向孩子发送道具并且不同。我在渲染父级之前制作了一个console.log,并且道具没问题,并在子组件的开头制作了一个相同道具的console.log,它是不同的。

这是父母:

  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;

这就是孩子(我从孩子身上删除了大部分东西,因为在收到错误的道具后,其他一切都是错误的,当我使用模拟道具时它可以工作):

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

导出默认游戏板;

我怀疑它与父级中的randomPlaceShip 方法有关,因为我在子级中收到的是一个与父级不同的数组,但好像它有自己的randomPlaceShip(有另一个结果) . randomePlaceShip 方法如下:

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

方法中的 console.log 与我在父级中得到的匹配;但是,在子组件中,显然是另一个 go to 该方法不会向我显示该 console.log,所以我不确定它是否真的在运行该方法。

【问题讨论】:

  • 我怀疑你正在改变数据,可能在这里? array[i + x][y] = ship.hitPoints[i];array 在该函数中是undefined,所以在您的编辑中丢失了一些东西。任何发生变化的数据(例如船舶位置)都需要存储在 React 状态中并通过 setState 调用进行更新,以便使用正确的数据触发重新渲染。你可能想要创建一个钩子 useGameboard,而不是函数 createGameboard,它以 React 可以理解的方式在内部存储其状态。
  • 没错,最后我设法使用setStateuseEffect 使它工作。我相信这不是改变数据的问题,而是再次以某种方式重新运行randomPlaceShip 函数。我将发布我是如何做到的,以便您检查它是否或多或少是您推荐的。

标签: javascript reactjs react-props react-component


【解决方案1】:

正如琳达所说,我设法通过使用setState 解决了这个问题。

这边:

  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,
  ]);

在这种情况下,函数 fillBoard 包含函数 randomePlaceShip 对所有需要玩的五艘船执行。

【讨论】:

  • 我认为您仍在改变状态,因为您只是调用 fillBoard(boards.userPrimaryGrid) 而没有将该结果分配给任何变量。每当您更改板对象时,您都需要返回该对象的新版本。
  • 我明白了!我要重新讨论一下,因为fillBoard 会影响板子内部的内容(即参数),我认为不需要将其分配给变量。我去看看,谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-11-24
  • 2021-09-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-07
  • 1970-01-01
相关资源
最近更新 更多