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
相关产品推荐
相关产品推荐

