Есть ли способ сопоставить дочерний компонент и родительский компонент в React, я получаю странные результаты

Я новичок в React и начал с учебника Tic Tak Toe в документации React.

Я пытаюсь создать 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(() => {

кажется, его ударили 2 раза.

Я не уверен, почему, но, возможно, из-за повторного рендеринга?

Предполагается, что это 3 строки по 3 столбца, но нумерация должна быть от 1 до 9.

Спасибо

У вас одинаковый идентификатор кнопки, и, вероятно, это вызывает некоторые проблемы. создайте отдельный buttonID и попробуйте

UDID 11.10.2023 07:37
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
1
61
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

buttonId и boardRowIndex для всех кнопок и строк здесь одинаковы. Когда вы увеличиваете buttonId в одной строке, это влияет на нумерацию в других строках.

Попробуйте создать метод, который создаст для вас идентификатор: сохраните отдельные значения buttonId для каждой строки и соответствующим образом вычислите значения идентификатора.

Попробуйте приведенный ниже код.

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

Большое спасибо за ваш ответ, к сожалению, он до сих пор не решил мою проблему, и поскольку существует несколько BoardRow, а rowIds, которые передаются, одинаковы на 3 итерациях BoardRow, ключ для <SquareButton /> имеет три одинаковых ключа. Я также хочу отображать число в каждом из SquareButton, но я не могу этого сделать, если у меня нет какого-либо счетчика за пределами области карты.

Luke Bennett 11.10.2023 11:06

@LukeBennett, эту часть я изначально не понял. Я обновил код. пожалуйста, проверьте. только код, который я обновил.

UDID 11.10.2023 12:09

Ах, отлично, это работает! Я изучу, чтобы больше не повторять ту же ошибку, большое спасибо за помощь.

Luke Bennett 11.10.2023 12:34

@ЛюкБеннетт, отлично !! вы можете принять ответ, если это сработает.

UDID 11.10.2023 12:41

Причина, по которой вы получаете странные результаты при сопоставлении дочернего компонента и родительского компонента в React, заключается в том, что вы воссоздаете дочерний компонент при каждом рендеринге родительского компонента. Это связано с тем, что вы используете свойство key для создания уникального ключа для каждого дочернего компонента, но не передаете свойство id дочернему компоненту.

Чтобы исправить это, вы можете передать свойство id из родительского компонента в дочерний компонент, используя ключевое свойство. Это гарантирует, что дочерний компонент будет воссоздан только при изменении свойства 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, для управления состоянием платы. Это позволит вам централизованно отслеживать идентификатор и другое состояние платы, а также обновлять состояние платы без необходимости повторной визуализации всего дерева компонентов.

Другой способ решить эту проблему — использовать виртуальную библиотеку DOM, например React Fiber. React Fiber позволяет обновлять DOM без необходимости повторной визуализации всего дерева компонентов. Это может сделать ваше приложение более быстрым и отзывчивым.

Большое спасибо за ваш ответ, однако я попробовал это, и, похоже, он дает те же результаты, что и код, который я использовал ранее. Кажется, эта строка const boardRows = [...Array(3).keys()].map((i) => { повторяется несколько раз, я не уверен, что ее вызывает.

Luke Bennett 11.10.2023 11:26

Другие вопросы по теме