React+TypeScript报错TS2304:无法访问post对象的title与body属性
React+TypeScript中TS2304错误:找不到'title'和'body'的解决方案
问题重现
你在React组件PostDetail中尝试展示文章标题和内容时,触发了TS2304错误,提示找不到title和body变量。
原代码
const PostDetail = () => { const { id } = useParams(); const [post, setPost] = useState({}); const getPost = async () => { try { const { data } = await axios.get( `https://jsonplaceholder.typicode.com/posts/${id}` ); setPost(data); console.log(data); } catch (err) { console.log(err); } }; useEffect(() => { getPost(); }, []); return ( <> <Header /> <Navigator /> <div className="App"> <h3>Post details: {id}</h3> <p>{title}</p> <p>{body}</p> </div> <Footer /> </> ); }; export default PostDetail;
报错信息
ERROR in src/pages/PostDetail.tsx:38:9 TS2304: Cannot find name 'title'. 36 | 37 | <h3>Post details: {id}</h3> 38 | <p>{title}</p> /// Cannot find name 'title'. | ^^^^^ 39 | <p>{body}</p> /// Cannot find name 'body'. 40 | 41 | ERROR in src/pages/PostDetail.tsx:39:9 TS2304: Cannot find name 'body'. 37 | <h3>Post details: {id}</h3> 38 | <p>{title}</p> /// Cannot find name 'title'. 39 | <p>{body}</p> /// Cannot find name 'body'. | ^^^^ 40 | 41 | 42 | </>
问题原因
- 变量未定义:你直接写了
{title}和{body},但这两个变量根本没在组件里声明过。实际上title和body是post对象的属性,必须通过post.title、post.body来访问。 - TypeScript类型缺失:
useState的初始值是空对象{},TypeScript无法推断post的具体类型,就算改成post.title,后续也会出现“属性'title'在类型'{}'上不存在”的类型错误。
修复步骤
步骤1:正确访问对象属性
把模板里的{title}改成{post.title},{body}改成{post.body},确保从post对象中读取属性。
步骤2:给post添加类型定义
创建一个Post接口,明确post的结构,让TypeScript能正确推断类型:
interface Post { id: number; title: string; body: string; userId: number; }
然后在useState中指定类型:
const [post, setPost] = useState<Post>({} as Post);
这里用{} as Post是因为初始值是空对象,通过类型断言告诉TS这符合Post类型。
步骤3:处理加载状态(可选但推荐)
接口请求是异步的,初始时post是空对象,直接渲染post.title可能会显示undefined。可以加个加载判断:
if (!post.id) { return <div>Loading...</div>; }
修复后的完整代码
import { useState, useEffect } from 'react'; import { useParams } from 'react-router-dom'; import axios from 'axios'; import Header from '../components/Header'; import Navigator from '../components/Navigator'; import Footer from '../components/Footer'; interface Post { id: number; title: string; body: string; userId: number; } const PostDetail = () => { const { id } = useParams<{ id: string }>(); const [post, setPost] = useState<Post>({} as Post); const getPost = async () => { try { const { data } = await axios.get( `https://jsonplaceholder.typicode.com/posts/${id}` ); setPost(data); console.log(data); } catch (err) { console.log(err); } }; useEffect(() => { if (id) { getPost(); } }, [id]); // 处理加载状态 if (!post.id) { return <div>Loading...</div>; } return ( <> <Header /> <Navigator /> <div className="App"> <h3>Post details: {id}</h3> <p>{post.title}</p> <p>{post.body}</p> </div> <Footer /> </> ); }; export default PostDetail;
内容的提问来源于stack exchange,提问作者Heidi
相关产品推荐
相关产品推荐

