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

React+Firebase笔记应用:获取数据后UI不更新问题求助

问题分析与解决方法

问题根源

你的代码存在异步操作执行顺序错误:
fetchNote是异步函数,但你在调用fetchNote()后立刻执行了setData(notesData)——此时异步请求还未完成,notesData仍是空数组,组件初始渲染时data为空,UI无法渲染内容。当异步请求完成、notesData被填充时,没有再次调用setData触发组件重新渲染,导致data始终为空,map方法无法执行。

修复方案

将setData移至异步函数内部,确保数据获取完成后再更新状态:

import { useEffect, useState } from 'react';
import { AiFillCaretUp } from 'react-icons/ai';
import './Card.css';

export default function Card(props) {
  const [showPara, setShowPara] = useState(false);
  const [data, setData] = useState([]);

  useEffect(() => {
    const fetchNote = async () => {
      let notesData = [];
      const response = await fetch('https://notes-keeper-react-default-rtdb.firebaseio.com/notes.json');
      const fetchedData = await response.json();
      for (const key in fetchedData) {
        notesData.push({ id: key, title: fetchedData[key].title, note: fetchedData[key].note });
      }
      setData(notesData); // 数据处理完成后更新状态
    };
    fetchNote();
  }, []);

  const toggleHandler = () => {
    setShowPara((preVal) => !preVal);
  };

  const paraClass = showPara ? 'card-para toggle' : 'card-para';
  const rotate = showPara ? 'icon rotate' : 'icon';
  return (
    <div className='container'>
      {data.map((card) => (
        <div className='card' key={card.id}>
          <div className='card-title' onClick={toggleHandler}>
            <h3>{card.title}</h3>
            <AiFillCaretUp className={rotate} />
          </div>
          <div className={paraClass}>
            <p>{card.note}</p>
          </div>
        </div>
      ))}
    </div>
  );
}

额外优化建议

  • 给异步操作添加错误处理,避免请求失败时组件无响应:
const fetchNote = async () => {
  try {
    let notesData = [];
    const response = await fetch('https://notes-keeper-react-default-rtdb.firebaseio.com/notes.json');
    if (!response.ok) throw new Error('数据请求失败');
    const fetchedData = await response.json();
    for (const key in fetchedData) {
      notesData.push({ id: key, title: fetchedData[key].title, note: fetchedData[key].note });
    }
    setData(notesData);
  } catch (err) {
    console.error('获取数据出错:', err);
  }
};
  • 当前showPara是全局状态,所有卡片会同时展开/折叠,建议将showPara改为按卡片id存储的状态(比如const [expandedIds, setExpandedIds] = useState({})),实现单张卡片独立控制展开折叠。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 12:41:24