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

React组件渲染状态初始化问题:filteredList未同步resDataList

问题原因与解决方案

核心误区

你对useState的初始化逻辑理解有误:useState的初始值参数只在组件第一次渲染时生效,后续组件重新渲染时,这个参数会被直接忽略,不会自动用新的resDataList去更新filteredList。所以当resDataList从空数组加载出数据后,filteredList还是保持第一次初始化的空数组,自然不会渲染内容。

修复步骤

  1. 添加useEffect监听resDataList变化
    在Body组件里新增一个useEffect,当resDataList加载完成(长度不为0)时,将其赋值给filteredList:
import { useState, useEffect } from 'react';

export const Body = () => {
  const resDataList = useResData();

  const [filteredList, setFilteredList] = useState([]);
  const [inputText, setInputText] = useState('');

  // 监听resDataList变化,更新filteredList初始值
  useEffect(() => {
    if (resDataList.length > 0) {
      setFilteredList(resDataList);
    }
  }, [resDataList]);

  const filterList = () => {
    let filtered = resDataList.filter((item) => item.info.avgRating > 4);
    setFilteredList(filtered);
  }

  if (resDataList.length === 0) return <Shimmer />;
        
  return (
    <div className="Body"> 
      <div className="search">
        <input
          className="search-input"
          value={inputText}
          onChange={(e) => setInputText(e.target.value)}
        />
        <button
          className="search-btn" 
          onClick={() => {
            let list = resDataList.filter((data) => 
              data.info.name.toLowerCase().includes(inputText.toLowerCase())
            );
            setFilteredList(list);
          }}
        >
          Search
        </button>
      </div>
      <div className="filter-btn">
        <button onClick={filterList}>Top Rated Restaurants</button>
      </div>
      <div className="cardContainer">
        {filteredList.map((item) =>
          <Link
            to={`restaurants/${item.info.id}`}
            key={item.info.id}
          >
            <Card resData={item?.info} />
          </Link>
        )}
      </div>
    </div>
  )
}
  1. 修复自定义钩子的语法问题
    原useResData里的getData声明存在语法错误,同时增加错误处理和默认值兜底:
import { useState, useEffect } from 'react';

const useResData = () => {
  const [resDataList, setResDataList] = useState([]);

  useEffect(() => {
    // 正确声明async函数
    const getData = async () => {
      try {
        let res = await fetch(
          "https://www.swiggy.com/dapi/restaurants/list/v5?lat=28.65200&lng=77.16630&is-seo-homepage-enabled=true&page_type=DESKTOP_WEB_LISTING"
        );
        let data = await res.json();
        // 兜底空数组,避免API结构变化导致undefined
        setResDataList(data?.data?.cards?.[4]?.card?.card?.gridElements?.infoWithStyle?.restaurants || []);
      } catch (err) {
        console.error('数据获取失败:', err);
        setResDataList([]);
      }
    }
    getData();
  }, [])

  return resDataList;
}

export default useResData;

额外优化点

  • 搜索逻辑中把inputText转成小写,避免大小写不匹配导致的搜索失效
  • 给setResDataList添加默认空数组,防止API返回结构变化时出现异常
  • 给fetch请求增加错误捕获,避免请求失败导致组件崩溃

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 03:47:34