简体   繁体   English

即使在分配了值后,键也是空的

[英]Key is null even after being assigned a value

This is my first attempt at React.这是我第一次尝试 React。 I'm trying to build a UI where I can drag and drop images and move their order around.我正在尝试构建一个 UI,我可以在其中拖放图像并移动它们的顺序。 I realize that first, this is going to require that each image has a unique key, but I can't find the correct way to do it.我意识到首先,这将要求每个图像都有一个唯一的密钥,但我找不到正确的方法来做到这一点。 I don't understand why, even though I am explicitly assigning a key, it is still null when I view the object on the console.我不明白为什么,即使我明确分配了一个键,当我在控制台上查看对象时它仍然为空。 I've tried:我试过了:

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

Which still gives me a key of null (I tried assigning the outer div its own key as well, but that didn't work either).这仍然给我一个null键(我也尝试为外部 div 分配自己的键,但这也不起作用)。

I've read that if key isn't specified, it defaults to the element's id in the array (I'm still getting a null value when key isn't specified but that was expected), so I tried to manually assign it我已经读过,如果没有指定 key,它默认为数组中元素的 id(当没有指定 key 时我仍然得到一个空值,但这是预期的),所以我尝试手动分配它

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

But that gave me this error:但这给了我这个错误:

Warning: Encountered two children with the same key, 2 .警告:遇到两个使用相同密钥2孩子。 Keys should be unique so that components maintain their identity across updates...键应该是唯一的,以便组件在更新时保持其身份...

That error continues with each new image added to the array even though the # increases with each error.即使#随着每个错误增加,每个新图像添加到数组中,该错误也会继续。 That is telling me that the key is increasing as it should, but for some reason, it is still not unique.这告诉我,密钥应该增加,但由于某种原因,它仍然不是唯一的。 My guess is that somehow 2 children are being created each time?我的猜测是每次都会以某种方式创建 2 个孩子? Regardless, this gives me the wrong output so I can't use it.无论如何,这给了我错误的输出,所以我不能使用它。

I've also tried simply this, which gives me the correct output, but I get the same warning as above except in place of # it says [object Object]我也简单地尝试过这个,它给了我正确的输出,但我得到了与上面相同的警告,除了#它说[object Object]

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

Here is my complete code for the component.这是我的组件完整代码。 When I check the object id in the drag event when moving around images, it is always undefined.当我在移动图像时检查拖动事件中的对象 ID 时,它始终未定义。 I just need to figure out what is going on with this unique key issue, but if you see anything wrong with the drag and drop functionality, I could use some pointers their also.我只需要弄清楚这个独特的关键问题发生了什么,但是如果您发现拖放功能有任何问题,我也可以使用一些指针。

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;

Here is a working sample that substitutes an array of integers for an array of images.这是一个用整数数组替换图像数组的工作示例。 I'll leave the image part to you as that seems incomplete in your example.我会将图像部分留给您,因为这在您的示例中似乎不完整。 The core bit of your solution is in the file named "images.js".您的解决方案的核心部分位于名为“images.js”的文件中。

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

There are just a couple of issues with your code:您的代码只有几个问题:

  1. As @Kyle rightly points out, you'll need some identifier for your dropped element.正如@Kyle 正确指出的那样,您将需要一些用于放置元素的标识符。 The easiest thing to use is the index as the id property.最容易使用的是将索引作为id属性。
 <span key={index} id={index} >
  1. The handler for the dragStart event does not match the function signature from the Event API. dragStart事件的处理程序与来自事件 API 的函数签名不匹配。 Which means you'll have to derive the id attribute value from the event object within the handler (which I've done in the solution provided):这意味着您必须从处理程序中的事件对象派生id属性值(我已在提供的解决方案中完成):
 onDragStart = (ev, id) => { ... }; Must be: onDragStart = (ev) => { ... };
  1. You were also using the .dataTransfer() method improperly.您还错误地使用了.dataTransfer()方法。 That setData() API requires a data type as the first argument and the value as the second.setData() API 需要数据类型作为第一个参数和值作为第二个参数。 The getData() API requires only the data type. getData() API 只需要数据类型。

You may find that using the index as the id becomes a bit troublesome if you attempt to manipulate the images by id which is also the array index.如果您尝试通过id操作图像,您可能会发现使用index作为id变得有点麻烦, id也是数组索引。 For example, removing a dropped image from the state will reindex the array of images.例如,从状态中删除已删除的图像将重新索引图像数组。 So you might consider using something different for the id attribute.因此,您可能会考虑对id属性使用不同的内容。

Hope this helps.希望这可以帮助。

Key is a prop, not an attribute.键是道具,而不是属性。 Props do not show up in the DOM, they get passed into the child components.道具不会出现在 DOM 中,它们会被传递到子组件中。

The key is a special prop that can be on normal elements in lists.关键是一个特殊的道具,可以在列表中的普通元素上。 It doesn't propagate into the DOM.它不会传播到 DOM 中。 Take a look at some of the codepens in this article.看看本文中的一些代码笔。 https://reactjs.org/docs/lists-and-keys.html . https://reactjs.org/docs/lists-and-keys.html

So所以

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

Will render as:将呈现为:

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

Inspecting the element will not show any key.检查元素不会显示任何键。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM