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

React Hooks中字典数据更新失败:日期格式化函数未执行求助

问题解决思路

核心问题分析

你的代码里useEffect依赖是空数组,会在组件首次挂载时执行,但此时数据库异步请求还未完成,data还是初始空数组[],所以data.forEach根本不会触发,自然不会打印"Heu"。另外pwease函数里的setData([...data, upDatis])是在追加新格式化对象,而非替换原数组对应元素,会导致数据重复叠加。


方案一:获取数据时直接格式化(推荐)

最合理的时机是拿到数据库数据后、存入useState前直接处理,无需额外useEffect:

const [data, setData] = useState([]);

useEffect(() => {
  const fetchAndFormat = async () => {
    const response = await db.collection('users').doc(auth.currentUser.uid).get();
    const rawAppointments = response.data().appointments;
    
    // 批量格式化所有预约的日期
    const formatted = rawAppointments.map(item => {
      const start = new Date(1970, 0, 1);
      start.setSeconds(item.startDate.seconds);
      
      const end = new Date(1970, 0, 1);
      end.setSeconds(item.endDate.seconds);
      
      return { ...item, startDate: start, endDate: end };
    });
    
    setData(formatted);
  };

  fetchAndFormat();
}, []);

方案二:用useEffect监听data变化处理

如果必须在data更新后再处理,需把data加入依赖数组,且一次性处理整个数组避免重复追加:

const [data, setData] = useState([]);

// 日期格式化工具函数
const toDateTime = (secs) => {
  const t = new Date(1970, 0, 1);
  t.setSeconds(secs);
  return t;
};

// 发起数据库请求
useEffect(() => {
  db.collection('users').doc(auth.currentUser.uid).get()
    .then(res => setData(res.data().appointments));
}, []);

// 监听data更新,执行格式化
useEffect(() => {
  if (data.length === 0) return;
  
  const formattedData = data.map(item => ({
    ...item,
    startDate: toDateTime(item.startDate.seconds),
    endDate: toDateTime(item.endDate.seconds)
  }));
  
  setData(formattedData);
  console.log('Heu');
}, [data]);

注意:方案二会触发两次setData(原始数据、格式化后数据),组件会额外渲染一次,性能不如方案一。


额外注意事项

  • 禁止在循环中多次调用setData:每次调用都会触发组件渲染,循环调用会造成不必要的性能损耗,应一次性生成完整格式化数组后再更新状态。
  • 数据库请求优先使用async/await语法,比链式then更易读和维护。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 23:25:20