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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 12:09:03