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

React+TypeScript中状态变量设置后渲染HTML的问题及解决

问题描述

我想在状态变量设置成功后渲染HTML块,定义了如下状态变量和赋值函数:

const formService:FormService=new FormService();

const [appointmentDate, setAppointmentDate] = useState<AppointmentDate>();
const [formattedDate, setFormattedDate ]=useState<string>()
const [formattedTime, setFormattedTime ]=useState<string>()
const [formattedTime20MinutesBefore, setFormattedTime20MinutesBefore] = useState<string>()


useEffect(()=>{
    init();
},[])

const init = async ()=>{
    await getAppointmentData();
    await organizeTheDates();
}

const getAppointmentData = async ()=>{
    const appointmentDateVar= await formService.getAppointmentPageInformation(3);
    setAppointmentDate(appointmentDateVar);
}

const organizeTheDates = async ()=>{
    if (appointmentDate) {
        // 格式化时间日期并设置状态
        const date:Date =(new Date(appointmentDate.dateTime));
        setFormattedDate(`${date.getDate().toString().padStart(2, '0')}/${(date.getMonth() + 1).toString().padStart(2, '0')}/${date.getFullYear()}`)
        setFormattedTime(`${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}`)

        const twentyMinutesBefore = new Date(date.getTime() - 20 * 60000);
        setFormattedTime20MinutesBefore(`${twentyMinutesBefore.getHours().toString().padStart(2, '0')}:${twentyMinutesBefore.getMinutes().toString().padStart(2, '0')}`);

    }
}

我通过以下判断控制页面渲染:

if(formattedDate != undefined && formattedTime != undefined ){
    return ( /* 页面内容 */ ) 
}else {
    return <div>loading</div>
}

但运行时页面一直停在loading状态,只有重新保存代码触发React重渲染后,才会正常显示页面。我猜测是useState的异步特性导致的问题,求解决方法。

更新

我根据Quentin的回答修改了部分代码:

const init = async ()=>{
    await organizeTheDates(await getAppointmentData());
}

const getAppointmentData = async ()=>{
    const appointmentDateVar=await formService.getAppointmentPageInformation(3);
    setAppointmentDate(appointmentDateVar)
    return appointmentDateVar;
}

解决思路与方案

问题核心:setAppointmentDate是异步操作,调用后appointmentDate状态不会立即更新。原代码中await getAppointmentData()仅等待接口请求完成,但此时appointmentDate还未更新,紧接着调用organizeTheDates()时,appointmentDate依然是undefined,导致格式化后的状态变量未被设置,页面一直停在loading。

最终修改方案

调整organizeTheDates函数,直接使用传入的接口返回数据,不再依赖状态变量:

// 修改organizeTheDates,接收接口返回的原始数据
const organizeTheDates = (appointmentDateVar: AppointmentDate) => {
    const date: Date = new Date(appointmentDateVar.dateTime);
    setFormattedDate(`${date.getDate().toString().padStart(2, '0')}/${(date.getMonth() + 1).toString().padStart(2, '0')}/${date.getFullYear()}`);
    setFormattedTime(`${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}`);

    const twentyMinutesBefore = new Date(date.getTime() - 20 * 60000);
    setFormattedTime20MinutesBefore(`${twentyMinutesBefore.getHours().toString().padStart(2, '0')}:${twentyMinutesBefore.getMinutes().toString().padStart(2, '0')}`);
}

// init函数保持修改后的逻辑
const init = async ()=>{
    const appointmentData = await getAppointmentData();
    organizeTheDates(appointmentData);
}

简化方案(可选)

如果不需要保留appointmentDate状态,可直接在接口请求完成后处理格式化,彻底避免异步状态更新问题:

// 移除appointmentDate状态
const [formattedDate, setFormattedDate ]=useState<string>()
const [formattedTime, setFormattedTime ]=useState<string>()
const [formattedTime20MinutesBefore, setFormattedTime20MinutesBefore] = useState<string>()

useEffect(()=>{
    init();
},[])

const init = async ()=>{
    const appointmentDateVar= await formService.getAppointmentPageInformation(3);
    const date: Date = new Date(appointmentDateVar.dateTime);
    setFormattedDate(`${date.getDate().toString().padStart(2, '0')}/${(date.getMonth() + 1).toString().padStart(2, '0')}/${date.getFullYear()}`);
    setFormattedTime(`${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}`);

    const twentyMinutesBefore = new Date(date.getTime() - 20 * 60000);
    setFormattedTime20MinutesBefore(`${twentyMinutesBefore.getHours().toString().padStart(2, '0')}:${twentyMinutesBefore.getMinutes().toString().padStart(2, '0')}`);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 08:35:14