页面渲染时transactions数组为空,渲染后却有值的问题咨询
问题原因及解决办法
核心问题
初始渲染空数组触发报错:Header组件初始化时,zustand里的
transactions是默认的空数组。如果代码里直接尝试访问数组元素的balance属性(比如transactions[0].balance),此时数组为空、元素是undefined,必然会抛出Cannot read properties of undefined (reading 'balance')错误。状态更新逻辑冗余:
getBalance方法里,你在forEach循环内部每push一条数据就调用set,既会触发多次不必要的组件重渲染,又因为异步请求完成时机晚于组件初始渲染,导致初始渲染时数组依然为空。异步代码写法混乱:
async函数里混用await和.then,逻辑不够清晰,容易引发时序问题。
修复步骤
1. 优化zustand状态更新逻辑
把状态更新操作移到循环外,等所有数据收集完成后一次性更新,同时简化异步代码:
const currentBalance = (set, get) => ({ transactions: [], getBalance: async () => { try { const snapshot = await getDocs(colBal); const transactions = snapshot.docs.map(doc => ({ ...doc.data(), id: doc.id })); set({ transactions }); console.log(transactions); } catch (err) { console.log(err.message); } }, });
2. 处理Header组件的空数组场景
在使用transactions前先判断数组是否有内容,避免访问undefined的属性:
const Header = () => { const getBalance = useStore((state) => state.getBalance); const transactions = useStore((state) => state.transactions); useEffect(() => { getBalance(); }, [getBalance]); // 示例:用条件判断或可选链安全访问balance const firstBalance = transactions.length > 0 ? transactions[0].balance : 0; // 或者用可选链语法:transactions[0]?.balance console.log(transactions); return ( <div> {/* 渲染时加入加载状态判断 */} {transactions.length > 0 ? ( <p>当前余额:{transactions[0].balance}</p> ) : ( <p>加载中...</p> )} </div> ); };
修改后,组件初始渲染会显示加载状态,等异步请求完成、状态更新后再渲染真实数据,就不会出现报错了。
内容的提问来源于stack exchange,提问作者Alex Tuiasosopo
相关产品推荐
相关产品推荐

