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

React初始渲染时数组对象过滤结果不显示,重渲染后正常

初始渲染过滤预订列表不显示的问题解决

问题描述

页面首次加载时,过滤后的预订数组无法展示;但保存代码触发热重载后,过滤结果能正常显示。尝试将过滤结果存入常量后调用setFilteredBookings,问题仍未解决。

问题根源

在useEffect的异步请求逻辑中,调用setBookings(bookingsresponse.data)后立刻用bookings状态数组做过滤操作。但React的useState更新是异步批量处理的,此时bookings还是初始的空数组[],过滤结果自然为空,导致初始渲染没有内容。热重载时组件重新初始化,bookings已缓存了之前的数据,过滤就能正常执行。

解决方案

方案1:直接使用接口返回的数据过滤

不要依赖刚更新的bookings状态,直接用接口返回的原始数据做过滤,再更新filteredBookings状态:

function Booking() {

  const name = localStorage.getItem('name');
  const email = localStorage.getItem('email');
  const [bookings, setBookings] = useState([]);
  const [filteredBookings,setFilteredBookings] = useState([]);

  useEffect( () => {
    const fetchBookings = async() => {
      try{
        const customerIDResponse = await axios.get(`http://localhost:5000/getUserID/${name}/${email}`);
        const bookingsresponse = await axios.get(`http://localhost:5000/getBookings/${customerIDResponse.data.SQLdata[0].customerid}`);
        const fetchedBookings = bookingsresponse.data;
        setBookings(fetchedBookings); 
        
        // 直接用接口返回的fetchedBookings过滤,避开异步状态更新的延迟
        const currentTime = new Date().getTime();
        const filtered = fetchedBookings.filter(booking => {
          const bookingTime = new Date(booking.bookingdate).getTime();
          return bookingTime >= currentTime;
        });
        setFilteredBookings(filtered);

      } catch(err){
        alert("Uncaught error contact owner of website");
      }
    }
    fetchBookings();
  },[])

  const handleDelete = async (bookingid) => {
    try{
      await axios.delete(`http://localhost:5000/deleteBooking/${bookingid}`);
      window.location.reload();
    } catch(err){
      alert("Uncaught error contact owner of website");
      console.log(err);
    }
  }

  return (
    <div className="main">
      <Navbar/>
      <div className="current-bookings-container">
        <div className="bookings-header">Bookings in the next week for {name}</div>
        <div className="current-bookings">
          {filteredBookings.map( booking => (
            <div className="booking" key={booking.bookingid}>
              <h1>Booking ID: {booking.bookingid}</h1>
              <p>Your booking date: {booking.bookingdate}</p>
              <p>The booking time is: {booking.bookingtime}</p>
              <button className="delete" onClick={()=>handleDelete(booking.bookingid)}>Delete</button>
              <button className="update"><Link to={`/booking/update/${booking.bookingid}`}>Update</Link></button>
            </div>
          ))}
        </div>
      </div>

      <button className="create-booking"><Link to="/booking/create">Create a Booking</Link></button>
    </div>
  )
}

方案2:去掉filteredBookings状态,渲染时实时计算(更推荐)

直接在渲染阶段根据bookings状态和当前日期计算过滤结果,避免维护额外状态导致的同步问题:

function Booking() {

  const name = localStorage.getItem('name');
  const email = localStorage.getItem('email');
  const [bookings, setBookings] = useState([]);

  useEffect( () => {
    const fetchBookings = async() => {
      try{
        const customerIDResponse = await axios.get(`http://localhost:5000/getUserID/${name}/${email}`);
        const bookingsresponse = await axios.get(`http://localhost:5000/getBookings/${customerIDResponse.data.SQLdata[0].customerid}`);
        setBookings(bookingsresponse.data); 
      } catch(err){
        alert("Uncaught error contact owner of website");
      }
    }
    fetchBookings();
  },[])

  const handleDelete = async (bookingid) => {
    try{
      await axios.delete(`http://localhost:5000/deleteBooking/${bookingid}`);
      window.location.reload();
    } catch(err){
      alert("Uncaught error contact owner of website");
      console.log(err);
    }
  }

  // 渲染时实时计算过滤后的列表
  const currentTime = new Date().getTime();
  const filteredBookings = bookings.filter(booking => {
    const bookingTime = new Date(booking.bookingdate).getTime();
    return bookingTime >= currentTime;
  });

  return (
    <div className="main">
      <Navbar/>
      <div className="current-bookings-container">
        <div className="bookings-header">Bookings in the next week for {name}</div>
        <div className="current-bookings">
          {filteredBookings.map( booking => (
            <div className="booking" key={booking.bookingid}>
              <h1>Booking ID: {booking.bookingid}</h1>
              <p>Your booking date: {booking.bookingdate}</p>
              <p>The booking time is: {booking.bookingtime}</p>
              <button className="delete" onClick={()=>handleDelete(booking.bookingid)}>Delete</button>
              <button className="update"><Link to={`/booking/update/${booking.bookingid}`}>Update</Link></button>
            </div>
          ))}
        </div>
      </div>

      <button className="create-booking"><Link to="/booking/create">Create a Booking</Link></button>
    </div>
  )
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 17:01:20