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

Firestore文档分类展示异常:点击切换按钮出现循环问题

问题原因

你遇到的无限循环异常,核心问题是按钮的onClick属性错误地直接执行了函数,而非传递函数引用。组件每次渲染时,handleUpcoming()和handlePast()都会被立即调用,调用后通过setAccounts更新状态,触发组件重新渲染,再次执行函数,形成无限循环。

修复后的完整代码
import React, { useState, useMemo } from 'react';
import './App.css';
import db from './firebase';
import 'react-toastify/dist/ReactToastify.css';

const App = () => {
  // 用useMemo缓存当前日期,避免每次渲染重复计算
  const currentDate = useMemo(() => new Date().toISOString().slice(0, 10), []);
  const [accounts, setAccounts] = useState([]);

  const handleUpcoming = async () => {
    try {
      const response = db.collection('accounts').where('schedule', '>', currentDate);
      const data = await response.get();
      const newAccounts = data.docs.map(item => ({ ...item.data(), id: item.id }));
      setAccounts(newAccounts);
    } catch (error) {
      console.error('获取即将到来的预约失败:', error);
      // 可在此添加toast提示用户错误
    }
  };

  const handlePast = async () => {
    try {
      const response = db.collection('accounts').where('schedule', '<', currentDate);
      const data = await response.get();
      const newAccounts = data.docs.map(item => ({ ...item.data(), id: item.id }));
      setAccounts(newAccounts);
    } catch (error) {
      console.error('获取历史预约失败:', error);
      // 可在此添加toast提示用户错误
    }
  };

  return (
    <div className="app-container">
      <h1>Appointments</h1>
      <div className="button-container">
        {/* 关键修改:去掉函数后的括号,传递函数引用 */}
        <button onClick={handleUpcoming}>Upcoming</button>
        <button onClick={handlePast}>Past</button>
        <div className="scrollbar">
          <table>
            {accounts.map(account => (
              /* 列表项添加唯一key属性,符合React性能优化要求 */
              <tr key={account.id}>
                <td className="appointmentDataOne">
                  {account.name}
                  <div className="appointmentDataTwo">{account.email}</div>
                </td>
                <td className="appointmentDataOne">{account.schedule}</td>
                <td className="appointmentDataTwo">{account.service}</td>
                <td className="appointmentDataTwo">{account.mobileNumber}</td>
              </tr>
            ))}
          </table>
        </div>
      </div>
    </div>
  );
};

export default App;
关键修改说明
  • 修复循环问题:将onClick={handleUpcoming()}改为onClick={handleUpcoming},确保只有点击按钮时才执行函数,而非组件每次渲染都执行。
  • 缓存当前日期:用useMemo缓存currentDate,避免组件每次渲染都重新创建Date对象并格式化,提升性能。
  • 添加列表key:为表格的<tr>添加key={account.id},React需要唯一key来高效更新列表,避免控制台警告。
  • 错误捕获:在异步函数中添加try/catch,捕获Firestore请求可能出现的错误,避免页面崩溃,同时方便调试。
  • 优化数据结构:将Firestore文档的id添加到数据中,既作为列表的唯一key,也方便后续对单个预约进行操作(如删除、编辑)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 20:35:27