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

React应用移动端视图数据已获取但不渲染问题求助

React应用移动端无法渲染内容的排查与解决

问题现象

桌面浏览器可正常展示数据,但切换至移动端视图(浏览器调试工具或真实手机)时,API已成功获取数据,但页面无法渲染内容。

核心问题排查

1. API响应结构的设备差异

两处组件均使用page_type=DESKTOP_WEB_LISTING请求API,Swiggy的API会根据该参数返回不同结构的卡片数据。移动端下卡片索引位置发生变化,导致通过固定索引cards[0]/cards[1]无法获取到目标数据。

2. 固定边距导致内容溢出

Dishes组件中图片容器使用了ml-32 mr-32的固定大边距,移动端屏幕宽度有限,该边距会挤压容器宽度,导致内容被挤出可视区域。

3. 响应式布局缺失

Body组件的筛选栏未做移动端适配,搜索框与按钮会出现挤压;餐厅卡片容器也无移动端边距处理,可能导致内容排版错乱。

解决方案

1. 适配API的设备响应结构

动态切换API的page_type参数,并通过遍历卡片而非固定索引获取数据,提升兼容性:

Body.js 修改fetchData函数

const fetchData = async () => {
    const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
    const pageType = isMobile ? "MOBILE_WEB_LISTING" : "DESKTOP_WEB_LISTING";
    const data = await fetch(`https://www.swiggy.com/dapi/restaurants/list/v5?lat=18.9777315&lng=72.8273249&is-seo-homepage-enabled=true&page_type=${pageType}`);
    const json = await data.json();
    
    // 动态查找餐厅数据卡片
    const restaurantCard = json?.data?.cards.find(card => card?.card?.card?.gridElements?.infoWithStyle?.restaurants);
    // 动态查找标题卡片
    const titleCard = json?.data?.cards.find(card => card?.card?.card?.header?.title);
    
    setTitle(titleCard?.card?.card?.header?.title || "热门餐厅");
    const restaurants = restaurantCard?.card?.card?.gridElements?.infoWithStyle?.restaurants || [];
    setListOfRestaurant(restaurants);
    setFilteredRestaurant(restaurants);
}

Dishes.js 修改fetchData函数

const fetchData = async () => {
    try {
        const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
        const pageType = isMobile ? "MOBILE_WEB_LISTING" : "DESKTOP_WEB_LISTING";
        const data = await fetch(`https://www.swiggy.com/dapi/restaurants/list/v5?lat=18.9777315&lng=72.8273249&is-seo-homepage-enabled=true&page_type=${pageType}`);
        const json = await data.json();
        
        // 动态查找菜品图片卡片
        const dishCard = json?.data?.cards.find(card => card?.card?.card?.imageGridCards?.info);
        setTitle(dishCard?.card?.card?.header?.title || "热门菜品");
        setDish(dishCard?.card?.card?.imageGridCards?.info || []);
    } catch (error) {
        console.error('数据获取失败:', error);
    }
};

2. 调整Dishes组件的响应式样式

移除固定大边距,改用响应式边距和尺寸:

// 修改标题区域边距
<div className='flex justify-between px-4'>
    <span className='font-bold text-xl sm:text-2xl'>{title}</span>
    <div className='flex text-xl sm:text-2xl'>
        <span onClick={scrollPrev} className='flex items-center justify-center w-8 p-1 h-8 mr-2 cursor-pointer bg-green-300 rounded-full'><GrFormPrevious /></span>
        <span onClick={scrollNext} className='flex items-center justify-center w-8 p-1 h-8 cursor-pointer bg-green-300 rounded-full'><GrFormNext /></span>
    </div>
</div>

// 修改图片容器样式
{dish.length > 0 ? (
    <div className="flex justify-start overflow-x-auto gap-4 px-4 mt-3 hide-scrollbar" ref={containerRef}>
        {dish.map(({ imageId }) => (
            <img key={imageId} className="w-[120px] sm:w-[144px] h-[150px] sm:h-[180px] m-auto" src={imageId ? `${CDN_URL}${imageId}` : DEFAULT_FOOD_IMAGE_URL} alt="dish-image" />
        ))}
    </div>
) : (
    <div className="px-4 py-8 text-center">暂无热门菜品</div>
)}

3. 为Body组件添加响应式布局

调整筛选栏和餐厅卡片容器的样式:

// 修改筛选栏布局
<div className="filter flex flex-wrap justify-center">
    <div className="searchBar m-2 p-2 w-full sm:w-auto">
        <input data-testid="searchInput" type="text" className="border border-solid py-1 pl-1 border-pink-100 rounded-sm" placeholder="搜索.." value={searchInput} onChange={(e) => { setSearchInput(e.target.value) }} />
        <button name="Search" className="px-4 py-1 m-2 bg-pink-100 rounded-lg" onClick={() => {
            const filteredRestaurant = listOfRestaurants.filter(rest => rest.info.name.toLowerCase().includes(searchInput.toLowerCase()));
            setFilteredRestaurant(filteredRestaurant)
        }}>Search</button>
    </div>
    <div className="searchBar p-2 flex items-center w-full sm:w-auto justify-center">
        <button className="px-4 py-1 bg-gray-100 rounded-lg" onClick={() => {
            const filteredList = listOfRestaurants.filter((res) => res.info.avgRating > 4.5);
            setFilteredRestaurant(filteredList)
        }}>Top Rated Restaurants</button>
    </div>
</div>

// 修改餐厅卡片容器边距
<div className="flex flex-wrap px-4">
    {filteredRestaurant ? (
        filteredRestaurant.map((restaurant) => (
            <Link key={restaurant?.info?.id} to={'/restaurants/' + restaurant?.info?.id}>
                {restaurant.info.avgRating > 4.5 ? (
                    <RestaurantCardBestSeller resData={restaurant} />
                ) : (
                    <RestaurantCard resData={restaurant} />
                )}
            </Link>
        ))
    ) : null}
</div>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 23:22:15