Как можно отобразить массив в React, передав его в value?

Почему при клике на двух компонентах <Square /> отображается значение "X", хотя через пропсы мы передаем массив значений value={squares}, а не конкретное значение из этого массива (например squares[0])? Проверка с использованием обычного JavaScript показывает предсказуемый результат в виде текстового представления всего массива в DOM элементе, а не одного его элемента, как это происходит в React.
  • 8 декабря 2023 г. 1:49
Ответы на вопрос 2
Для отображения массива в React можно использовать метод `map()`. В данном случае можно пройтись по массиву `squares` и создать компонент `Square` для каждого элемента массива, передавая значение в пропс `value`.

Например, в компоненте, отображающем доску с крестиками и ноликами, можно использовать следующий код:

```jsx
import React from 'react';
import Square from './Square';

function Board({ squares }) {
  return (
    <div>
      {squares.map((value, index) => (
        <Square key={index} value={value} />
      ))}
    </div>
  );
}

export default Board;
```

Теперь рассмотрим вопрос о том, почему при клике на двух компонентах `<Square />` отображается значение "X", хотя пропсы передаются как массив `value={squares}`.

В React каждый компонент является независимым и имеет собственное состояние. В данном случае, при клике на компонент `<Square />`, мы обновляем состояние этого компонента и присваиваем ему значение "X". Однако, так как каждый компонент создается отдельно в цикле при отображении массива, каждый компонент имеет свое собственное состояние.

То есть, при клике на один компонент `<Square />` мы обновляем его состояние и отображаем "X", при клике на другой компонент `<Square />` мы обновляем его состояние и тоже отображаем "X". При этом, компоненты не влияют друг на друга и не знают о существовании друг друга.

Для того чтобы сделать так, чтобы при клике на один компонент `<Square />` обновлялись значения всех компонентов сразу, нужно хранить массив `squares` в состоянии родительского компонента и передавать его значения в пропсы каждого компонента `<Square />`. При клике на один компонент, мы должны обновлять состояние родительского компонента и передавать новое значение массива `squares` в пропсы. Тогда, при рендере каждого компонента `<Square />` будет использоваться актуальное значение из состояния.

Пример кода, демонстрирующий такой подход:

```jsx
import React, { useState } from 'react';
import Square from './Square';

function Board() {
  const [squares, setSquares] = useState(Array(9).fill(null));

  const handleClick = (index) => {
    const newSquares = [...squares];
    newSquares[index] = "X";
    setSquares(newSquares);
  }

  return (
    <div>
      {squares.map((value, index) => (
        <Square
          key={index}
          value={value}
          onClick={() => handleClick(index)}
        />
      ))}
    </div>
  );
}

export default Board;
```

Теперь, при клике на компонент `<Square />`, мы обновляем состояние родительского компонента `Board` и передаем новые значения массива `squares` каждому компоненту `<Square />`.
Ты при клике изменяешь состояние squares, заменяешь массив на "X", все твои компоненты Square слушают состояние squares через пропсы, соответственно он везде и будет "X". 

Если тебе нужно инкапсулировать состояние squares, перенеси его в компонент Square как и обработчик клика.
Похожие вопросы