我有我的反应页面的问题,其中它的文章ID是从url读取,其中的内容,然后从我的后端API基于此ID提取。但是页面无法工作,在控制台中显示此错误:
Uncaught TypeError: Cannot read properties of undefined (reading 'attributes')
示例URL:
http://localhost:1337/api/project/1
我从URL获得的ID与这一行:
const { id } = useParams();
和输出{id}实际上显示了url中的数字。所以我认为这部分工作如期进行。
我的路由是这样的:
<Route path="/project/:id" element = { <Project /> } />
此外,我用这一行从API获取内容:
fetch("http://localhost:1337/api/projects/"+id, { headers, method: 'GET' })
但是当我试图使用这个ID从后端获取正确的文章时,它不会正常工作。
console.log显示第一个undefined几次,然后才真正列出正确的内容(虽然五次,但不是我认为应该是一次)。
从console.log(项目)
定义
VM327 installHook.js:2116 undefined
bundle.js: 2870未定义的
VM327 installHook.js:2116 undefined
bundle.js:2870 {id: 1,属性:{…}}
VM327 installHook.js:2116 {id: 1,属性:{…}}
bundle.js:2870 {id: 1,属性:{…}}
VM327 installHook.js:2116 {id: 1,属性:{…}}
bundle.js:2870 {id: 1,属性:{…}}
VM327 installHook.js:2116 {id: 1,属性:{…}}
API方案如下:
// 20230401201253
// http://localhost:1337/api/projects/1
{
"data": {
"id": 1,
"attributes": {
"Title": "Resort number one,
"Projecttext": "Text about project",
"createdAt": "2023-03-12T21:27:11.674Z",
"updatedAt": "2023-03-12T21:27:17.222Z",
"publishedAt": "2023-03-12T21:27:17.220Z"
}
},
"meta": {
}
}
这里是完整的演示代码(我已经删除了很多引导内容,但留下了重要的部分)。我想要工作的数据类型是这样的(并在代码中应用这一点,使页面加载空白与提到的未定义错误):
{project.attributes.Title}
{project.attributes.Projecttext}
// etc
import React from 'react';
import ReactDOM from 'react-dom/client';
import { useEffect, useState } from 'react';
import { Link } from "react-router-dom";
import { useParams } from 'react-router-dom';
// Parses the JSON returned by a network request
const parseJSON = (resp) => (resp.json ? resp.json() : resp);
// Checks if a network request came back fine, and throws an error if not
const checkStatus = (resp) => {
if (resp.status >= 200 && resp.status < 300) {
return resp;
}
return parseJSON(resp).then(resp => {
throw resp;
});
};
const headers = { 'Content-Type': 'application/json' };
const ProjectOne = () => {
const [error, setError] = useState(null);
const [project, setProject] = useState();
// fetch id from url
const { id } = useParams();
useEffect(() => {
fetch("http://localhost:1337/api/projects/"+id, { headers, method: 'GET' })
.then(checkStatus)
.then(parseJSON)
.then(({ data }) => setProject(data))
.catch((error) => setError(error))
}, [])
if (error) {
// Print errors if any
return <div>An error occured: {error.message}</div>;
}
return (
<>
// This id works
{ id }
<div className="app">
// this writes out a couple of nulls, before it writes out the intended "project" array
{ console.log(project) }
<div key={id}>
// this doesn't work, and makes the page load blank, with null-errors in the console
<h3>{project.attributes.Title}</h3>
</div>
</div>
</>
);
}
export default ProjectOne;
我相信我在这里错过了一些重要的东西,但我不太确定下一步该去哪里。如有任何帮助,我将不胜感激。
const [project, setProject] = useState();
您已将初始状态设置为未定义。这是一件很正常的事情,但是您需要在组件的其余部分中预料到这一点。如果您试图访问project.attributes.Title
而不检查未定义,您将得到一个异常。
所以根据你想在加载时显示的内容,你可以替换整个输出:
if (error) {
// Print errors if any
return <div>An error occured: {error.message}</div>;
}
if (!project) {
return <div>Loading...</div>
// Or to render nothing:
// return null;
}
// The rest of your code can stay the same
return (
<>
...
</>
)
或者只是替换ui中需要数据的部分:
return (
<>
{id}
<div className="app">
<div key={id}>
<h3>{project ? project.attributes.Title : "Loading..."}</h3>
</div>
</div>
</>
);