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
关键修复点
- 移除
async关键字,恢复Hook的同步函数属性。 - 重构
fetchPosts,去掉冗余回调,改用标准async/await写法并添加错误捕获。 - 给
useState设置初始空数组,明确初始状态。 - 完善useEffect依赖,确保userId变化时重新触发请求。
- 增加参数校验,避免无意义的API调用。
内容的提问来源于stack exchange,提问作者schwarzsky
相关产品推荐
相关产品推荐

