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

页面渲染时transactions数组为空,渲染后却有值的问题咨询

问题原因及解决办法

核心问题

  1. 初始渲染空数组触发报错:Header组件初始化时,zustand里的transactions是默认的空数组。如果代码里直接尝试访问数组元素的balance属性(比如transactions[0].balance),此时数组为空、元素是undefined,必然会抛出Cannot read properties of undefined (reading 'balance')错误。

  2. 状态更新逻辑冗余:getBalance方法里,你在forEach循环内部每push一条数据就调用set,既会触发多次不必要的组件重渲染,又因为异步请求完成时机晚于组件初始渲染,导致初始渲染时数组依然为空。

  3. 异步代码写法混乱: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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 07:52:41