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

React useRef值更新后子组件未获取最新值问题排查

问题根因

你的代码存在3个核心问题,导致ref更新后子组件拿不到预期值:

  • useRef本身的特性是更新.current属性不会触发组件重渲染,但这不是你当前场景的核心问题:你试图在同一次map遍历的子组件渲染过程中修改ref值,让后续遍历的子组件拿到新值,但React的渲染流程不保证遍历执行顺序(并发渲染模式下遍历可能被打断、重放、调整顺序),渲染过程中修改外部状态(包括ref的current)本身就是违反React纯渲染要求的写法,会直接导致状态不一致。
  • 子组件的forwardRef写法完全错误:你写的React.forwardref存在拼写错误(正确API名是React.forwardRef),且没有按照API要求传入渲染函数,子组件根本拿不到你传入的ref值。
  • 逐小时AM/PM的计算逻辑存在设计缺陷:靠渲染过程中触发回调改共享ref的方式,只能处理一次AM/PM切换,如果展示的卡片超过12小时(比如展示24小时预报会切换两次AM/PM),逻辑会直接错乱,且每个卡片独立基于初始时间计算偏移,没有统一的时间基准。
修复方案

不要用ref存跨组件共享的时段状态,也不要在子组件渲染过程中修改父组件状态,直接在父组件遍历阶段提前算好每个卡片对应的小时、AM/PM标识,把计算完成的结果传给子组件即可,这是最稳定、最符合React设计规范的写法:

修复后的父组件代码(index.js)

import type { NextPage } from 'next'
import WeatherCard from '../components/WeatherCard'
import { motion } from 'framer-motion'
import { useState } from 'react'
import { PropsType } from '../types'

const Home: NextPage<PropsType> = (props) => {
  const [time,setTime] = useState(new Date());

  // 提前计算所有卡片所需数据,不在子组件渲染阶段修改共享状态
  const cardList = determineWeatherCardsArr().map((el, index) => {
    // 计算当前卡片对应的准确时间
    const cardTime = new Date(time.getTime() + index * 60 * 60 * 1000);
    // 直接调用原生API获取12小时制的小时和AM/PM,不需要手动维护切换逻辑
    const [hour, ampm] = cardTime.toLocaleString('en-US', {
      hour: 'numeric',
      hour12: true
    }).split(' ');

    return {
      ...el,
      cardTitle: `${hour}${ampm}`
    }
  })
  
  return (
    <div>
      <main>
         {cardList.map((el,index) => (
           <motion.div key={index}>
             <WeatherCard 
               weather={el.weather} 
               temp={el.temp} 
               cardTitle={el.cardTitle}
             />
           </motion.div>
         ))}
      </main>
    </div>
  )
}

export default Home

修复后的子组件代码(WeatherCard.js)

不需要使用forwardRef,直接接收父组件计算好的props即可:

import Image from "next/image";

const WeatherCard = (props) => {
  return(
    <div className="">
      <h3 className="">{props.cardTitle}</h3>
    </div>
  )
}

export default WeatherCard

如果你坚持要用ref实现,需要先修正forwardRef的写法,同时把ref更新逻辑放到useEffect中执行,更新ref后还要触发一次父组件重渲染才能让子组件拿到新值,但这种写法依然存在渲染顺序导致的状态不稳定问题,不推荐使用。

内容的提问来源于stack exchange,提问作者H.b

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 17:42:14