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

React组件渲染空白求助:API请求正常但页面无内容

React表单提交后页面空白,API调用正常但组件不渲染数据

问题描述

提交表单后页面显示空白,但API调用返回了正确的JSON数据(结构如下),控制台能看到React元素被创建,但页面就是不渲染。

期望的API返回JSON结构:

[
    {
        "trackName": "Beira de Piscina (Remix)",
        "trackUri": "spotify:track:6a0kQTjyGmfwBF0tLVgEha",
        "artistImage": "https://i.scdn.co/image/ab67616d0000b27366127aa6c868a01e97f62d64"
    },
    {
        "trackName": "Beira de Piscina",
        "trackUri": "spotify:track:25XUxLporfgzl2rf2mtgmj",
        "artistImage": "https://i.scdn.co/image/ab67616d0000b2738e2cc04d7c1ed2beb3216ff2"
    }
]

以下是出现问题的组件代码:

import {useState} from "react";

export default function SearchTracks() {

    const [formSuccess, setFormSuccess] = useState(false)
    const [trackList, setTracklist] = useState()

    const handleSubmit = async (event: any) => {
        event.preventDefault()

        const data = {
            trackName: event.target.trackName.value
        }

        const endpoint = `http://myEndPoint:8080/tracks?trackName=${data.trackName}`
        const options = {
            method: 'GET',
            headers: {
                'access-token': 'MyAccessToken'
            }
        }
        const response = await fetch(endpoint, options)

        const result = await response.json()
        setFormSuccess(true)

        setTracklist(result)
    };

    const renderTrack = (trackListResponse) : any => {
        const myMap = new Map(Object.entries(trackListResponse))
        return myMap.forEach((trackValue) => {
            return trackValue.map(track => {
                let value = buildTrackContainer(track)
                console.log(value)
                return value
            })
        })
    }

    const buildTrackContainer = (track) => {
       console.log("Building track: " + track.trackName)
       return <li key={track.trackUri}>
            <p>{track.trackName}</p>
            <p>{track.trackUri}</p>
            <img src={track.artistImage}/>
        </li>
    }

    return (
        <div>
            {formSuccess ?
                <ul>
                    { renderTrack({trackList}) }
                </ul>
                :
                <form onSubmit={handleSubmit}>
                    <label htmlFor="trackName">Track Name</label>
                    <input type="text" id="trackName" name="trackName" required/>
                    <button type="submit">Submit</button>
                </form>
            }
        </div>
    )
}

控制台能打印出React元素,但页面空白,附控制台日志截图和页面结果截图。


问题原因与修复方案

核心问题1:forEach无返回值导致渲染内容为空

renderTrack函数中使用myMap.forEach(...),但forEach方法不会返回任何值(始终返回undefined),即便内部调用trackValue.map生成了React元素数组,最终也无法传递给渲染层。

核心问题2:冗余的Map包装与参数传递

你传递给renderTrack的是{trackList}(一个包含trackList属性的对象),再用Object.entries转成Map完全多余——API返回的trackList本身就是数组,直接遍历即可。

修复后的代码

import {useState} from "react";

export default function SearchTracks() {
    // 初始化空数组,避免undefined引发的潜在错误
    const [formSuccess, setFormSuccess] = useState(false)
    const [trackList, setTracklist] = useState<any[]>([])

    const handleSubmit = async (event: any) => {
        event.preventDefault()
        const trackName = event.target.trackName.value
        const endpoint = `http://myEndPoint:8080/tracks?trackName=${trackName}`
        const options = {
            method: 'GET',
            headers: {
                'access-token': 'MyAccessToken'
            }
        }
        const response = await fetch(endpoint, options)
        const result = await response.json()
        
        // 先更新数据再切换状态,确保渲染时已有数据
        setTracklist(result)
        setFormSuccess(true)
    };

    // 直接遍历trackList数组生成元素
    const renderTracks = () => {
        return trackList.map(track => buildTrackContainer(track))
    }

    // 添加参数类型定义,提升代码可读性与类型安全
    const buildTrackContainer = (track: {trackName: string; trackUri: string; artistImage: string}) => {
        return (
            <li key={track.trackUri}>
                <p>{track.trackName}</p>
                <p>{track.trackUri}</p>
                {/* 添加alt属性,优化可访问性 */}
                <img src={track.artistImage} alt={`${track.trackName} artist image`} />
            </li>
        )
    }

    return (
        <div>
            {formSuccess ? (
                <ul>{renderTracks()}</ul>
            ) : (
                <form onSubmit={handleSubmit}>
                    <label htmlFor="trackName">Track Name</label>
                    <input type="text" id="trackName" name="trackName" required/>
                    <button type="submit">Submit</button>
                </form>
            )}
        </div>
    )
}

额外优化点

  • 初始化trackList为空数组,避免初始状态为undefined的潜在问题
  • 调整状态更新顺序,确保渲染时数据已准备完毕
  • 给函数参数添加类型定义,提升代码健壮性
  • 为图片添加alt属性,符合Web可访问性标准

内容的提问来源于stack exchange,提问作者João Fulgêncio

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 19:45:31