Ключ нулевой, даже после присвоения значения - PullRequest
0 голосов
/ 02 февраля 2019

Это моя первая попытка React.Я пытаюсь создать пользовательский интерфейс, где я могу перетаскивать изображения и перемещать их порядок.Я понимаю, что сначала для этого потребуется, чтобы у каждого изображения был уникальный ключ, но я не могу найти правильный способ сделать это.Я не понимаю, почему, хотя я явно назначаю ключ, он все еще нулевой, когда я смотрю объект на консоли.Я попытался:

<div>
  {this.props.imageArray.map((image, index) => (
    <span
      key={index}
    >
      {image}
    </span>
  ))}
</div>;

, который все еще дает мне ключ null (я также попытался назначить внешнему div его собственный ключ, но это тоже не сработало).

Я читал, что если ключ не указан, по умолчанию используется идентификатор элемента в массиве (я все еще получаю нулевое значение, когда ключ не указан, но это ожидалось), поэтому япопытался назначить его вручную

<div>
  {this.props.imageArray.map(image => (
    <span key={this.props.images.length}>{image}</span>
  ))}
</div>;

Но это дало мне эту ошибку:

Предупреждение. Обнаружено два ребенка с одним и тем же ключом, 2.Ключи должны быть уникальными, чтобы компоненты сохраняли свою идентичность при каждом обновлении ...

Эта ошибка продолжается с каждым новым изображением, добавляемым в массив, даже если # увеличивается с каждой ошибкой.Это говорит мне о том, что ключ увеличивается, как и должен, но по какой-то причине он все еще не уникален.Я предполагаю, что как-то 2 детей создаются каждый раз?Несмотря на это, это дает мне неправильный вывод, поэтому я не могу его использовать.

Я также просто попробовал это, что дает мне правильный вывод, но я получаю то же предупреждение, что и выше, за исключением #, где написано [object Object]

<div>
  {this.props.imageArray.map(image => (
    <span key={image}>{image}</span>
  ))}
</div>;

Вот мой полный код для компонента.Когда я проверяю идентификатор объекта в событии перетаскивания при перемещении изображений, он всегда не определен.Мне просто нужно выяснить, что происходит с этой уникальной ключевой проблемой, но если вы видите что-то не так с функциональностью перетаскивания, я мог бы использовать некоторые указатели и их.

class Images extends Component {
    state = {
      arrayOfImages: [...this.props.imageArray],
      droppedImage: []
    };

    onDragStart = (ev, id) => {
      ev.dataTransfer.setData("id", id);
    };

    onDrop = ev => {
      let id = ev.dataTransfer.getData("id");
      let draggedImage = this.state.arrayOfImages.filter(function(image) {
        return image === id;
      });

      this.setState({
        droppedImage: draggedImage
      });
    };
    onDragOver = ev => {
      ev.preventDefault();
    };

    render() {
      return (
        <React.Fragment>
          <div>
            {this.props.imageArray.map((image, index) => (
              <span
                key={index}
                onDragStart={this.onDragStart}
                draggable //I know this isn't necessary for images
              >
                {image}
              </span>
            ))}
          </div>
          <div
            className="dropTarget"
            onDragOver={e => this.onDragOver(e)}
            onDrop={e => this.onDrop(e)}
          >
            {this.state.droppedImage}
          </div>
        </React.Fragment>
      );
    }
  }

  export default Images;

Ответы [ 2 ]

0 голосов
/ 02 февраля 2019

Вот рабочий пример, который заменяет массив целых чисел на массив изображений.Я оставлю часть изображения для вас, так как это кажется неполным в вашем примере.Основной бит вашего решения находится в файле с именем "images.js".

https://codesandbox.io/s/013jrvn2pp

Есть только пара проблем с вашим кодом:

  1. Как правильно заметил @Kyle, вам понадобится некоторый идентификатор для вашего отброшенного элемента.Самым простым в использовании является индекс как свойство id.
<span   
   key={index}   
    id={index} 
>
Обработчик события dragStart не соответствует сигнатуре функции из API событий.Это означает, что вам придется извлечь значение атрибута id из объекта события в обработчике (что я сделал в предоставленном решении):
onDragStart = (ev, id) => {
 ... 
};
Must be:
onDragStart = (ev) => {
 ...
};
Вы также неправильно использовали метод .dataTransfer().Этот setData() API требует тип данных в качестве первого аргумента и значение в качестве второго.API getData() требует только тип данных.

Вы можете обнаружить, что использование index в качестве id становится немного проблематичным, если вы пытаетесь манипулировать изображениями с помощью id, который также является индексом массива.Например, удаление отброшенного изображения из состояния приведет к повторной индексации массива изображений.Поэтому вы можете рассмотреть возможность использования чего-то другого для атрибута id.

Надеюсь, это поможет.

0 голосов
/ 02 февраля 2019

Ключ - это реквизит, а не атрибут.Реквизиты не отображаются в DOM, они передаются в дочерние компоненты.

Ключ - это специальная опора, которая может быть на обычных элементах в списках.Это не распространяется в DOM.Взгляните на некоторые из codepens в этой статье.https://reactjs.org/docs/lists-and-keys.html.

Итак

<span
  key={index}
  id={index}
>
  {image}
</span>

Будет отображаться как:

<span id=*value_of_index*> *value_of_image* </span>

Проверка элемента не покажет какой-либо ключ.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...