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) => ())}
在我的代码中,我尝试获取下面 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) => ())}