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

React组件请求后端数据后访问story的title属性提示undefined报错

问题根源

  1. 响应状态判断逻辑错误:response.status 是数字类型,代码中与字符串 '200' 做全等判断,所有正常响应都会被误判为错误,触发错误分支的 setStoryState({ error: err }) 操作。这个操作直接全量覆盖了state,初始化时定义的story字段丢失,导致storyState.story变为undefined,访问undefined.title就触发了对应的 TypeError。
  2. 控制台打印的是对象引用:你在控制台看到的story对象是请求完成、state更新后的最新值,和组件第一次渲染时的状态并不一致,所以会出现「打印能看到属性但访问报错」的矛盾表现。
  3. 缺少加载状态判断:组件首次渲染时fetch请求还未返回结果,直接读取属性不符合异步渲染的逻辑。

修复方案

1. 修正状态更新和判断逻辑

  • 把状态判断的'200'改为数字200
  • 更新state时使用展开运算符保留原有字段,避免字段丢失
  • 补充请求catch分支捕获网络异常
  • 修正请求URL中多余的斜杠

2. 渲染时增加状态判断

加载完成前展示加载提示,也可以用可选链?.做兜底容错。

修正后的完整代码:

import { useState, useEffect } from 'react';
import styled from 'styled-components';

export const StoryPage = () => {
    const [storyState, setStoryState] = useState({
        story: {},
        isLoaded: false,
        error: null,
    });

    const queryString = window.location.search;
    const urlParams = new URLSearchParams(queryString);
    const id = urlParams.get('storyid');

    useEffect(() => {
        fetch('http://localhost:5000/getstory?storyid=' + id)
            .then((response) => {
                console.log('response is', response);
                // 修正:status是数字类型,和数字200比较
                if (response.status !== 200) {
                    let err = new Error();
                    err.message = 'Invalid response code: ' + response.status;
                    // 修正:展开原有state,保留其他字段
                    setStoryState({ ...storyState, error: err });
                }
                return response.json();
            })
            .then((json) => {
                console.log('json is', json);
                // 修正:展开原有state,保留其他字段
                setStoryState({
                    ...storyState,
                    story: json.story,
                    isLoaded: true,
                });
            })
            // 补充:捕获网络异常
            .catch(err => {
                setStoryState({...storyState, error: err})
            });
    }, []);

    // 错误状态处理
    if (storyState.error) {
        return <div>请求出错:{storyState.error.message}</div>
    }
    // 加载状态处理
    if (!storyState.isLoaded) {
        return <div>加载中...</div>
    }

    return (
        <>
            <h1>test</h1>
            {/* 可选:加可选链做双重兜底 */}
            <h1>{storyState.story?.title}</h1>
        </>
    );
};

export default StoryPage;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 03:54:03