Double nested Array in JSON leads to TypeError: Cannot read properties of null (reading 'map')

Double nested Array in JSON leads to TypeError: Cannot read properties of null (reading 'map')

在我的代码中,我尝试获取下面 JSON 中的 2 个缩略图网址。我只能进入第一个数组 the

<>{post.attributes.description}</> 

但我无法进入第二个数组

<>{img.attributes.formats.thumbnail.url}</>

我收到错误:

TypeError: Cannot read properties of null (reading 'map')

  11 | <div key={post.id}>
  12 |   <>{post.attributes.description}</>
> 13 |   {post.attributes.image["data"].map((img) => (
     |                                 ^
  14 |     <div key={img.id}>
  15 |       <>{img.attributes.name}</>
  16 |     </div>

代码

import React from "react";

export default function Home({ posts }) {
  return (
    <div>
      {posts["data"].map((post) => (
        <div key={post.id}>
          <>{post.attributes.description}</>
          {post.attributes.image["data"].map((img) => (
            <div key={img.id}>
              <>{img.attributes.formats.thumbnail.url}</>
            </div>
          ))}
        </div>
      ))}
    </div>
  );
}

export async function getStaticProps() {
  const res = await fetch("http://localhost:1337/api/games?populate=*");
  const posts = await res.json();
  return {
    props: { posts },
  };
}

JSON:

{
  "data": [
    {
      "id": 1,
      "attributes": {
        "title": "gw2",
        "description": "test",
        "createdAt": "2022-02-18T21:11:17.405Z",
        "updatedAt": "2022-02-20T16:39:07.188Z",
        "publishedAt": "2022-02-18T21:11:18.345Z",
        "image": {
          "data": [
            {
              "id": 1,
              "attributes": {
                "name": "ddda8Screenshot-02-EfLA-1920x1080.jpg",
                "alternativeText": "ddda8Screenshot-02-EfLA-1920x1080.jpg",
                "caption": "ddda8Screenshot-02-EfLA-1920x1080.jpg",
                "width": 1920,
                "height": 1080,
                "formats": {
                  "thumbnail": {
                    "name": "thumbnail_ddda8Screenshot-02-EfLA-1920x1080.jpg",
                    "hash": "thumbnail_ddda8_Screenshot_02_Ef_LA_1920x1080_9e7cc15b9c",
                    "ext": ".jpg",
                    "mime": "image/jpeg",
                    "width": 245,
                    "height": 138,
                    "size": 7.88,
                    "path": null,
                    "url": "/uploads/thumbnail_ddda8_Screenshot_02_Ef_LA_1920x1080_9e7cc15b9c.jpg"
                  },
                  "large": {
                    "name": "large_ddda8Screenshot-02-EfLA-1920x1080.jpg",
                    "hash": "large_ddda8_Screenshot_02_Ef_LA_1920x1080_9e7cc15b9c",
                    "ext": ".jpg",
                    "mime": "image/jpeg",
                    "width": 1000,
                    "height": 563,
                    "size": 80.97,
                    "path": null,
                    "url": "/uploads/large_ddda8_Screenshot_02_Ef_LA_1920x1080_9e7cc15b9c.jpg"
                  },
                  "medium": {
                    "name": "medium_ddda8Screenshot-02-EfLA-1920x1080.jpg",
                    "hash": "medium_ddda8_Screenshot_02_Ef_LA_1920x1080_9e7cc15b9c",
                    "ext": ".jpg",
                    "mime": "image/jpeg",
                    "width": 750,
                    "height": 422,
                    "size": 49.54,
                    "path": null,
                    "url": "/uploads/medium_ddda8_Screenshot_02_Ef_LA_1920x1080_9e7cc15b9c.jpg"
                  },
                  "small": {
                    "name": "small_ddda8Screenshot-02-EfLA-1920x1080.jpg",
                    "hash": "small_ddda8_Screenshot_02_Ef_LA_1920x1080_9e7cc15b9c",
                    "ext": ".jpg",
                    "mime": "image/jpeg",
                    "width": 500,
                    "height": 281,
                    "size": 25.21,
                    "path": null,
                    "url": "/uploads/small_ddda8_Screenshot_02_Ef_LA_1920x1080_9e7cc15b9c.jpg"
                  }
                },
                "hash": "ddda8_Screenshot_02_Ef_LA_1920x1080_9e7cc15b9c",
                "ext": ".jpg",
                "mime": "image/jpeg",
                "size": 258.19,
                "url": "/uploads/ddda8_Screenshot_02_Ef_LA_1920x1080_9e7cc15b9c.jpg",
                "previewUrl": null,
                "provider": "local",
                "provider_metadata": null,
                "createdAt": "2022-02-20T16:37:41.604Z",
                "updatedAt": "2022-02-20T16:37:41.604Z"
              }
            },
            {
              "id": 2,
              "attributes": {
                "name": "76ade04-Flame-Frost-Dyes-1920x1080.jpg",
                "alternativeText": "76ade04-Flame-Frost-Dyes-1920x1080.jpg",
                "caption": "76ade04-Flame-Frost-Dyes-1920x1080.jpg",
                "width": 1920,
                "height": 1080,
                "formats": {
                  "thumbnail": {
                    "name": "thumbnail_76ade04-Flame-Frost-Dyes-1920x1080.jpg",
                    "hash": "thumbnail_76ade04_Flame_Frost_Dyes_1920x1080_749230faa0",
                    "ext": ".jpg",
                    "mime": "image/jpeg",
                    "width": 245,
                    "height": 138,
                    "size": 10.28,
                    "path": null,
                    "url": "/uploads/thumbnail_76ade04_Flame_Frost_Dyes_1920x1080_749230faa0.jpg"
                  },
                  "large": {
                    "name": "large_76ade04-Flame-Frost-Dyes-1920x1080.jpg",
                    "hash": "large_76ade04_Flame_Frost_Dyes_1920x1080_749230faa0",
                    "ext": ".jpg",
                    "mime": "image/jpeg",
                    "width": 1000,
                    "height": 563,
                    "size": 113.82,
                    "path": null,
                    "url": "/uploads/large_76ade04_Flame_Frost_Dyes_1920x1080_749230faa0.jpg"
                  },
                  "medium": {
                    "name": "medium_76ade04-Flame-Frost-Dyes-1920x1080.jpg",
                    "hash": "medium_76ade04_Flame_Frost_Dyes_1920x1080_749230faa0",
                    "ext": ".jpg",
                    "mime": "image/jpeg",
                    "width": 750,
                    "height": 422,
                    "size": 70.06,
                    "path": null,
                    "url": "/uploads/medium_76ade04_Flame_Frost_Dyes_1920x1080_749230faa0.jpg"
                  },
                  "small": {
                    "name": "small_76ade04-Flame-Frost-Dyes-1920x1080.jpg",
                    "hash": "small_76ade04_Flame_Frost_Dyes_1920x1080_749230faa0",
                    "ext": ".jpg",
                    "mime": "image/jpeg",
                    "width": 500,
                    "height": 281,
                    "size": 34.66,
                    "path": null,
                    "url": "/uploads/small_76ade04_Flame_Frost_Dyes_1920x1080_749230faa0.jpg"
                  }
                },
                "hash": "76ade04_Flame_Frost_Dyes_1920x1080_749230faa0",
                "ext": ".jpg",
                "mime": "image/jpeg",
                "size": 348.37,
                "url": "/uploads/76ade04_Flame_Frost_Dyes_1920x1080_749230faa0.jpg",
                "previewUrl": null,
                "provider": "local",
                "provider_metadata": null,
                "createdAt": "2022-02-20T16:37:41.616Z",
                "updatedAt": "2022-02-20T16:37:41.616Z"
              }
            }
          ]
        }
      }
    },
    {
      "id": 2,
      "attributes": {
        "title": "game2 ",
        "description": "jkgbr",
        "createdAt": "2022-02-18T21:12:12.108Z",
        "updatedAt": "2022-02-18T21:12:12.967Z",
        "publishedAt": "2022-02-18T21:12:12.965Z",
        "image": {
          "data": null
        }
      }
    },
    {
      "id": 3,
      "attributes": {
        "title": "game3",
        "description": "sqlekjlbkgt",
        "createdAt": "2022-02-18T21:16:18.886Z",
        "updatedAt": "2022-02-18T21:16:19.996Z",
        "publishedAt": "2022-02-18T21:16:19.995Z",
        "image": {
          "data": null
        }
      }
    },
    {
      "id": 4,
      "attributes": {
        "title": "game 4",
        "description": "sadjglklasdhbl",
        "createdAt": "2022-02-19T06:25:06.589Z",
        "updatedAt": "2022-02-19T06:25:07.300Z",
        "publishedAt": "2022-02-19T06:25:07.297Z",
        "image": {
          "data": null
        }
      }
    },
    {
      "id": 5,
      "attributes": {
        "title": "game 5 notebook",
        "description": "create on notebook",
        "createdAt": "2022-02-19T06:46:04.335Z",
        "updatedAt": "2022-02-19T06:46:05.471Z",
        "publishedAt": "2022-02-19T06:46:05.469Z",
        "image": {
          "data": null
        }
      }
    }
  ],
  "meta": {
    "pagination": {
      "page": 1,
      "pageSize": 25,
      "pageCount": 1,
      "total": 5
    }
  }
}

任何人都可以在这方面帮助 JS 新手吗?

看看你的数据。大多数“post”记录都有这个:

"image": {
  "data": null
}

data 为空。所以当你这样做时:

post.attributes.image["data"].map(...)

您正试图在 null 上呼叫 .map()。错误告诉你的是什么:

Cannot read properties of null (reading 'map')

如果值可能是 null,请在使用前检查 null。例如:

post.attributes.image["data"]?.map(...)

或更明确地说:

post.attributes.image["data"] ?
  post.attributes.image["data"].map(...) :
  null

基本上任何时候你的 object/array 可能是 null,你需要确保它 不是 null在尝试 de-reference 之前。

在这种情况下,我假设您不希望代码在遇到 null 值时产生任何输出。如果不是这种情况,那么当您遇到 null 引用时,您可以有条件地生成您喜欢的任何输出。

我检查过您在 image.data 中的一个条目中有一个空条目。检查 ID 为 2.

的第二个条目
{
  "id": 2,
  "attributes": {
    "title": "game2 ",
    "description": "jkgbr",
    "createdAt": "2022-02-18T21:12:12.108Z",
    "updatedAt": "2022-02-18T21:12:12.967Z",
    "publishedAt": "2022-02-18T21:12:12.965Z",
    "image": {
      "data": null
    }
  }
},

当 map 尝试读取每个 post 中的整个图像数组时,如果它发现一个空条目,它将中断。有帮助的是在 JS 中使用 optional chaining operator "?."。这可以防止 Array.map 发现 null 或 undefined 时它不会破坏整个 React 渲染。

{post.attributes.image?.["data"]?.map((img) => ())}