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

NextJS自定义usePosts钩子无法响应状态变化,仅返回空对象求助

usePosts自定义Hook始终返回空对象的原因及修复

根本原因:自定义Hook被定义为异步函数

React明确要求自定义Hook必须是同步函数。你将usePosts声明为async函数,这会导致Hook返回的是一个Promise对象,而非你预期的状态值posts。组件调用该Hook时,拿到的是Promise而非实际数据,所以表现为始终返回空对象(或undefined)。

其他需要修正的问题

  • 未初始化useState默认值:useState()未传入初始值,初始状态为undefined,容易和API返回的空数据混淆。
  • useEffect依赖不全:依赖数组仅包含status,缺少userId。当userId变更时,不会触发新的数据请求,导致数据不更新。
  • 无效的状态调试:setPosts(p)后立即console.log(posts),由于React状态更新是异步的,此处打印的是更新前的旧值,无法反映当前状态。

修复后的代码

import { useEffect, useState } from "react"

const usePosts = (userId, status) => {
    const [posts, setPosts] = useState([]) // 初始化空数组作为默认值

    const fetchPosts = async (userId) => {
        try {
            const res = await fetch(
                `${process.env.NEXT_PUBLIC_API_URL}/posts/findbycreator`,
                {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({ id: userId }),
                }
            )
            const data = await res.json()
            setPosts(data.posts || []) // 兜底处理API返回为空的情况
        } catch (err) {
            console.error('获取帖子失败:', err)
            setPosts([])
        }
    }

    useEffect(() => {
        // 同时校验状态和用户ID,避免无效请求
        if (status !== 'loading' && userId) {
            fetchPosts(userId)
        }
    }, [status, userId]) // 补充userId到依赖数组

    return posts
}

export default usePosts

关键修复点

  1. 移除async关键字,恢复Hook的同步函数属性。
  2. 重构fetchPosts,去掉冗余回调,改用标准async/await写法并添加错误捕获。
  3. 给useState设置初始空数组,明确初始状态。
  4. 完善useEffect依赖,确保userId变化时重新触发请求。
  5. 增加参数校验,避免无意义的API调用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 20:48:19