You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Strapi+React博客开发:Fetch API状态存储与数据访问疑问

React对接Strapi API状态访问异常的解决方法

用Strapi作为CMS、React作为前端搭建博客时,碰到了一个问题:将完整API响应JSON通过setPosts(json)存入state后,无法通过posts.data[0].attributes.Title访问标题数据;但如果仅存入attributes部分setPosts(json.data[0].attributes),就能通过posts.Title正常获取内容。

完整代码

import React, { useState, useEffect } from "react";

const App = () => {
    const [posts, setPosts] = useState({});

    useEffect(() => {
        const url = "http://localhost:1337/api/blogs";
        const options = {
            headers: {
                Authorization: process.env.REACT_APP_STRAPI_TOKEN,
            },
        };
        const fetchData = async () => {
            try {
                const res = await fetch(url, options);
                const json = await res.json();
                // 可行但希望能直接用setPosts(json)
                setPosts(json.data[0].attributes);
                console.log(json);
            } catch (err) {
                console.log(err);
            }
        };

        fetchData();
    }, []);
    return <div className="test">{posts.Title}</div>;
};

export default App;

Postman返回的完整API响应

{
    "data": [
        {
            "id": 1,
            "attributes": {
                "Title": "First Blog Post",
                "CreationDate": "2023-03-29",
                "Content": "My first blog test. Grabbing API endpoints.\n\nimage in the middle of the  text.\n```\ntest code\n```\n\n\n![Screenshot 2023-02-26 at 6.23.08 PM.png](http://localhost:1337/uploads/Screenshot_2023_02_26_at_6_23_08_PM_ca2f96ffd1.png)",
                "createdAt": "2023-03-30T02:01:59.255Z",
                "updatedAt": "2023-03-30T02:02:06.214Z",
                "publishedAt": "2023-03-30T02:02:06.123Z"
            }
        },
        {
            "id": 2,
            "attributes": {
                "Title": "Blog 2 ",
                "CreationDate": "2023-04-01",
                "Content": "test content 2",
                "createdAt": "2023-04-02T20:53:26.950Z",
                "updatedAt": "2023-04-02T20:53:30.963Z",
                "publishedAt": "2023-04-02T20:53:30.884Z"
            }
        }
    ],
    "meta": {
        "pagination": {
            "page": 1,
            "pageSize": 25,
            "pageCount": 1,
            "total": 2
        }
    }
}

问题原因

核心是React初始状态与异步渲染的冲突:

  • 初始state设为{},组件第一次渲染时posts是空对象,此时访问posts.data会得到undefined,继续访问[0].attributes.Title会直接抛出Cannot read properties of undefined的错误,导致组件渲染失败。
  • 而仅存attributes时,第一次渲染posts.Title是undefined,但不会触发报错,等异步请求完成state更新后,组件重新渲染就能拿到正确值。

解决方法

1. 初始化匹配API结构的state

把初始state改成和完整响应一致的结构,避免渲染时访问不存在的属性:

const [posts, setPosts] = useState({ data: [] });

2. 渲染时使用可选链判断

用可选链操作符?.防止访问undefined属性报错,即使初始state为空也能正常渲染:

return <div className="test">{posts.data?.[0]?.attributes?.Title}</div>;

3. 添加加载状态

在数据请求完成前显示加载提示,彻底避免渲染未就绪的数据:

import React, { useState, useEffect } from "react";

const App = () => {
    const [posts, setPosts] = useState({ data: [] });
    const [loading, setLoading] = useState(true);

    useEffect(() => {
        const url = "http://localhost:1337/api/blogs";
        const options = {
            headers: {
                Authorization: process.env.REACT_APP_STRAPI_TOKEN,
            },
        };
        const fetchData = async () => {
            try {
                const res = await fetch(url, options);
                const json = await res.json();
                setPosts(json);
                setLoading(false);
                console.log(json);
            } catch (err) {
                console.log(err);
                setLoading(false);
            }
        };

        fetchData();
    }, []);

    if (loading) return <div>加载中...</div>;
    return <div className="test">{posts.data[0].attributes.Title}</div>;
};

export default App;

内容的提问来源于stack exchange,提问作者Kyle

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 21:17:11