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

React中API调用后设置document title出现TypeError的问题求助

问题根源与解决方案

你遇到的问题核心在于React的setState是异步操作——调用setBlogPost后,组件状态并不会立刻更新,所以你紧接着去访问blogPost.title.rendered时,blogPost还是初始的空对象{},自然会抛出Cannot read properties of undefined (reading 'rendered')的错误。

为什么你的两种尝试都失败了?

  1. 第一种写法的then链:
    最后一个then回调里,setBlogPost(post[0])刚刚触发,但状态还没完成更新,此时blogPost仍然是初始的空对象,根本没有title属性。
  2. 第二种async/await写法:
    同样的道理,setBlogPost(post[0])是异步的,调用后立刻访问blogPost,拿到的还是更新前的旧值。

两种可行的修复方案

方案1:直接使用API返回的原始数据设置标题

既然你已经在fetch的回调里拿到了完整的post[0]数据,完全不需要等到React状态更新,直接用这个数据来设置标题即可:

const getPost = async () => {
  try {
    const response = await fetch(blogPostURL);
    if (!response.ok) throw new Error('请求失败');
    const post = await response.json();
    // 先检查post[0]是否存在,避免API返回空数组的情况
    if (post[0]) {
      document.title = post[0].title.rendered;
      setBlogPost(post[0]);
    }
  } catch (err) {
    console.error('获取文章失败:', err);
  } finally {
    setLoading(false);
  }
}

或者用Promise链式写法:

const getPost = () => {
  fetch(blogPostURL)
    .then(response => {
      if (!response.ok) throw new Error('请求失败');
      return response.json();
    })
    .then(post => {
      if (post[0]) {
        document.title = post[0].title.rendered;
        setBlogPost(post[0]);
      }
      setLoading(false);
    })
    .catch(err => {
      console.error('获取文章失败:', err);
      setLoading(false);
    })
}

方案2:用useEffect监听blogPost状态变化

如果你必须依赖React状态来设置标题,可以新增一个useEffect,监听blogPost的变化,当状态更新完成后再修改标题:

const BlogPost = () => {
  const [loading, setLoading] = useState(true);
  const [blogPost, setBlogPost] = useState({});
  let blogPostURL = dgAPI.getPostFromSlug + useParams().slug;

  const getPost = async () => {
    try {
      const response = await fetch(blogPostURL);
      if (!response.ok) throw new Error('请求失败');
      const post = await response.json();
      setBlogPost(post[0] || {}); // 确保即使post[0]不存在,状态也是对象
    } catch (err) {
      console.error('获取文章失败:', err);
    } finally {
      setLoading(false);
    }
  }

  useEffect(() => {
    getPost();
  }, []);

  // 监听blogPost变化,更新标题
  useEffect(() => {
    // 可选链操作符避免访问不存在的属性报错
    if (blogPost.title?.rendered) {
      document.title = blogPost.title.rendered;
    }
  }, [blogPost]); // 依赖项设为blogPost,状态变化时触发

  return (
    <> ... </>
  )
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 06:55:02