index 在 React array.Map 函数中没有按预期工作

index isn't working as expected in React array.Map function

我正在尝试从 React 中的 array.map 函数中删除重复项,但我不确定为什么会收到 "Cannot read property of undefined" 错误。

下面的代码没有 return 任何结果,这是我所期望的,因为 video.project.id 等于 videos[i].project.id:

this.props.videos.map((video, i, videos) => {
    if (video.project.id !== videos[i].project.id) {
        return (
            <option
                key={video.id}
                value={video.project.id}
            >
              {video.project.projectName}
            </option>
        )
    }
})

所以我认为下面的代码应该 return 每个条目之一,但我却得到了错误:

this.props.videos.map((video, i, videos) => {
    if (video.project.id !== videos[i - 1].project.id) {
        return (
            <option
                key={video.id}
                value={video.project.id}
            >
              {video.project.projectName}
            </option>
        )
    }
})

谁能告诉我这里缺少什么?或者有更好的过滤方法吗?

.map() 总是 returns 一个相同长度的数组。默认情况下,函数将 return 'undefined'。所以你的数组可能看起来像 [optionComponent, undefined, undefined, optionComponent] 等

如果您要过滤,请尝试在地图旁边使用 Array.filter():

this.props.videos
.filter(video => video.project.id !== this.props.videos[i - 1].project.id)
.map((video, i, videos) => {
        return (
            <option
                key={video.id}
                value={video.project.id}
            >
              {video.project.projectName}
            </option>
        )
})

此外,"Cannot read property of undefined" 可能是因为索引 -1 (0 - 1) 未定义

编辑:我不确定过滤器函数中的回调是否可以解决问题。您可以使用 reduce 来使用对象来跟踪唯一值,然后将其转回数组:

uniqueVideos = Object.values(this.props.videos.reduce((prev, curr) => ({ ...prev, [curr.project.id]: curr }), {}))

所以地图不过滤。它每次都遍历每个项目和 returns 某些东西。您可能正在寻找过滤器。我使用了一个普通的 for 循环,因为在这种情况下它可能更容易理解

function filterVideos(){
    const ids = [];
    const videoDivs = [];
    for(const video of this.props.videos){
        if(ids.includes(video.id)){
            continue
        }
        ids.push(video.id);
        videoDivs.push(
            <option
                key={video.id}
                value={video.project.id}
            >
                {video.project.projectName}
            </option>
        )
    }
    return videoDivs
}

好的,这成功了。谢谢帕特里克埃文斯,这对我来说应该是显而易见的!我必须在 if 语句中添加 "i > 0"。

this.props.videos.map((video, i, videos) => {
    if (i > 0 && video.project.id !== videos[i - 1].project.id) {

        return (
            <option
                key={video.id}
                value={video.project.id}
            >{video.project.projectName}
            </option>
        )
    }
})