javascript 有没有办法在React中Map一个子组件和一个父组件,我得到了奇怪的结果

cld4siwp  于 2023-10-14  发布在  Java
关注(0)|答案(2)|浏览(102)

我是React的新手,已经开始使用React文档中的Tic Tak Toe教程。
我试图创建3个boardRows和3列宽的squareButtons
请让我知道我正在尝试做的事情是否正常,以及是否有更好的方法来做/接近它。
我会非常感激的,谢谢
这就是这段代码返回的内容,下面是我的代码:

import {useState} from "react";

export default function Board() {
    let buttonId = 1;
    let boardRowIndex = 0;

    function SquareButton({ id }) {
        return <button className="square">{id}</button>;
    }
    
    function BoardRow() {
        const squareButtons = [...Array(3).keys()].map(() => {
            const squareButton = <SquareButton key={buttonId - 1} id={buttonId} />;
            
            buttonId++;
            
            return squareButton;
        });
        
        return (
            <div className="board-row">
                { squareButtons }
            </div>
        );
    }
    
    const boardRows = [...Array(3).keys()].map(() => {
        const boardRow = <BoardRow key={boardRowIndex}/>;

        boardRowIndex++;

        return boardRow;
    });
        
    
    // The first squareButton begins at 4 now for some reason, and then skipping out numbers that aren't being displayed
    return (
        <>
            { boardRows }
        </>
    );
}

我试过在devtools中调试,

const boardRows = [...Array(3).keys()].map(() => {

好像被打了两次。
我不知道为什么,但也许是因为重新渲染。
它应该是3行3列,但编号应该是1 - 9。
谢谢你

tzxcd3kk

tzxcd3kk1#

所有按钮和行的buttonIdboardRowIndex在这里都是相同的。当您在一行中递增buttonId时,它会影响其他行中的编号。
尝试创建一个方法,为您创建id createId,为每行维护单独的buttonId值,并相应地计算id值。
试试下面的代码。

import React from 'react';

export default function Board() {
  const generateBoard = () => {
    const board = new Array(3).fill(null).map(() => new Array(3).fill(null));
    let currentId = 1;

    return board.map((row) =>
      row.map(() => {
        const id = currentId++;
        return { id, number: id };
      })
    );
  };

  const initialBoard = generateBoard();

  const SquareButton = ({ id, number }) => {
    return <button className="square">{number}</button>;
  };

  const BoardRow = ({ rowButtons }) => {
    const squareButtons = rowButtons.map(({ id, number }) => {
      return <SquareButton key={id} id={id} number={number} />;
    });

    return (
      <div className="board-row">
        {squareButtons}
      </div>
    );
  };

  const boardRows = initialBoard.map((rowButtons, rowIndex) => {
    return <BoardRow key={rowIndex} rowButtons={rowButtons} />;
  });

  return (
    <>
      {boardRows}
    </>
  );
}
1zmg4dgp

1zmg4dgp2#

在React中Map子组件和父组件时会得到奇怪的结果的原因是因为你在父组件的每次渲染中都重新创建了子组件。这是因为您正在使用key prop为每个子组件生成一个唯一的key,但您没有将id prop传递给子组件。
要解决这个问题,可以使用键prop将id prop从父组件传递给子组件。这将确保子组件仅在id属性更改时重新创建。

import { useState } from "react";

export default function Board() {
  let buttonId = 1;
  let boardRowIndex = 0;

  function SquareButton({ id }) {
    return <button className="square">{id}</button>;
  }

  function BoardRow() {
    const squareButtons = [...Array(3).keys()].map((i) => {
      const squareButton = <SquareButton key={i} id={buttonId} />;

      buttonId++;

      return squareButton;
    });

    return (
      <div className="board-row">
        {squareButtons}
      </div>
    );
  }

  const boardRows = [...Array(3).keys()].map((i) => {
    const boardRow = <BoardRow key={i} />;

    return boardRow;
  });

  // The first squareButton begins at 4 now for some reason, and then skipping out numbers that aren't being displayed
  return (
    <>
      {boardRows}
    </>
  );
}

还有其他一些方法来解决这个问题。一种方法是使用Redux这样的状态管理库来管理板的状态。这将允许您在一个集中的位置跟踪电路板的id和其他状态,并更新电路板的状态,而不必重新呈现整个组件树。
解决这个问题的另一种方法是使用像React Fiber这样的虚拟DOM库。React Fiber允许您更新DOM,而无需重新渲染整个组件树。这可以使您的应用程序更快,响应更快。

相关问题