React中数据加载完成后如何重新渲染自定义hook的返回结果
问题原因
useState的初始值仅会在组件首次渲染时计算一次,首次渲染时自定义hook还在加载数据,gamePlays为0,后续gamePlays更新不会自动同步到selected.count。- 你声明的
useEffect仅添加了gamePlays依赖,但是回调函数为空,没有执行更新selected的逻辑,自然无法同步最新值。 - 补充:你提供的
useLoadSpecficRecords代码中直接使用了未定义的username变量,会导致接口请求报错,需要先补全登录用户的获取逻辑。
修复方案
1. 先修正自定义hook的错误
// useLoadSpecficRecords Hook 修正版 import { useState, useEffect } from 'react' import { API, Auth } from 'aws-amplify' import { listRecordGames } from '../graphql/queries' const useLoadSpecficRecords = (date) => { const [loading, setLoading] = useState(true) const [games, setData] = useState([]) useEffect(() => { fetchGames(date) }, [date]) const fetchGames = async (date) => { try { const formatedDate = await date // 补全获取当前登录用户的逻辑 const user = await Auth.currentAuthenticatedUser() const username = user.username let records = await API.graphql({ query: listRecordGames, variables: { filter: { owner: { eq: username }, createdAt: { contains: formatedDate }, }, }, }) const allGames = records.data.listRecordGames.items const filteredGames = allGames.map(({ name, players, winners }) => { return { gameName: name, players: players, winners: winners, } }) setLoading(false) setData(filteredGames) } catch (err) { console.error(err) setLoading(false) } } return { games, loading } } export default useLoadSpecficRecords
2. 组件侧修正
根据你的使用场景二选一即可:
场景A:selected.count不需要单独修改,仅同步游戏数量
直接删除单独的useState声明,实时计算即可,避免多状态同步问题:
const { games, loading } = useLoadSpecficRecords(today) // 直接实时计算,数据更新会自动同步 const selected = { count: games.length } // 渲染时可以配合loading做加载态处理 if(loading) return <div>加载中...</div>
场景B:selected.count需要支持用户手动修改,需要单独维护状态
在useEffect中监听games.length变化,主动更新selected:
const { games, loading } = useLoadSpecficRecords(today) const gamePlays = games.length const [selected, setSelected] = useState({ count: gamePlays, }) // 监听gamePlays变化,主动更新状态 useEffect(() => { setSelected(prev => ({ ...prev, count: gamePlays })) }, [gamePlays])
内容的提问来源于stack exchange,提问作者Tyler Morales
相关产品推荐
相关产品推荐

