即使分配了值,键也为空

时间:2019-02-02 01:01:49

标签: javascript reactjs drag-and-drop key

这是我对React的第一次尝试。我正在尝试构建一个UI,可以在其中拖放图像并移动它们的顺序。我意识到,首先,这将要求每个图像都具有唯一的密钥,但是我找不到正确的方法。我不明白为什么,即使我显式分配了一个键,当我在控制台上查看对象时,它仍然为null。我尝试过:

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

哪个仍然给我一个null的键(我也尝试为外部div分配自己的键,但是那也不起作用)。

我已经读到,如果未指定key,则默认为数组中元素的id(当未指定key但这是预期值时,我仍会得到null值),因此我尝试手动分配

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

这是我完整的组件代码。当我在图像中移动时在拖动事件中检查对象ID时,它始终是未定义的。我只需要弄清楚这个唯一的关键问题是怎么回事,但是如果您发现拖放功能有什么问题,我也可以使用一些指针。

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 :(得分:1)

这是一个有效的示例,它将整数数组替换为图像数组。我将图像部分留给您,因为在您的示例中这似乎并不完整。解决方案的核心部分是名为“ images.js”的文件。

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

您的代码只有几个问题:

  1. 正如@Kyle正确指出的那样,您将需要一些标识符 删除的元素。最容易使用的是将索引作为id 财产。
<span   
   key={index}   
    id={index} 
>
  1. dragStart事件的处理程序与事件API中的函数签名不匹配。这意味着您必须从处理程序中的事件对象派生id属性值(我已经在提供的解决方案中完成了此操作):
onDragStart = (ev, id) => {
 ... 
};
Must be:
onDragStart = (ev) => {
 ...
};
  1. 您还使用了不正确的.dataTransfer()方法。该setData() API需要将数据类型作为第一个参数,将值作为第二个参数。 getData() API仅需要数据类型。

您可能会发现,如果尝试通过index(也是数组索引)来操纵图像,那么将id用作id会有些麻烦。例如,从状态中删除掉的图像将重新索引图像阵列。因此,您可以考虑为id属性使用其他内容。

希望这会有所帮助。

答案 1 :(得分:0)

键是道具,不是属性。道具未显示在DOM中,而是传递到子组件中。

键是一个特殊的道具,可以放在列表中的普通元素上。它不会传播到DOM中。看看本文中的一些代码库。 https://reactjs.org/docs/lists-and-keys.html

所以

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

将呈现为:

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

检查元素不会显示任何键。