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

React使用fetch获取数据得到字符串而非对象数组的问题

问题:Express返回JSON字符串而非数组,无法使用.map渲染页面

我用Express搭建后端,搭配存储对象数组的JSON文件,但客户端使用fetch获取数据时得到的是字符串类型。已确认JSON格式无误,希望获取数组类型数据以使用.map方法渲染页面。

JSON文件内容

[  
  {     
    "title":"Death Bed",
    "artist":"Powfu",
    "artwork":"https://samplesongs.netlify.app/album-arts/death-bed.jpg",
    "url":"https://samplesongs.netlify.app/Death%20Bed.mp3",
    "id":"1"
 },
 {     
    "title":"Bad Liar",
    "artist":"Imagine Dragons",
    "artwork":"https://samplesongs.netlify.app/album-arts/bad-liar.jpg",
    "url":"https://samplesongs.netlify.app/Bad%20Liar.mp3",
    "id":"2"
 },
 {     
    "title":"Faded",
    "artist":"Alan Walker",
    "artwork":"https://samplesongs.netlify.app/album-arts/faded.jpg",
    "url":"https://samplesongs.netlify.app/Faded.mp3",
    "id":"3"
 },
 {     
    "title":"Hate Me",
    "artist":"Ellie Goulding",
    "artwork":"https://samplesongs.netlify.app/album-arts/hate-me.jpg",
    "url":"https://samplesongs.netlify.app/Hate%20Me.mp3",
    "id":"4"
 },
 {     
    "title":"Solo",
    "artist":"Clean Bandit",
    "artwork":"https://samplesongs.netlify.app/album-arts/solo.jpg",
    "url":"https://samplesongs.netlify.app/Solo.mp3",
    "id":"5"
 },
 {     
    "title":"Without Me",
    "artist":"Halsey",
    "artwork":"https://samplesongs.netlify.app/album-arts/without-me.jpg",
    "url":"https://samplesongs.netlify.app/Without%20Me.mp3",
    "id":"6"
 }
]

后端Server代码(原问题代码)

const express = require('express')
const app = express()
const port = 5000
const fs = require('fs');

const songList = fs.readFileSync('data/songs.json', 'utf8');

app.get("/songList",(req,res)=> 
{
    res.json(songList)
})

app.listen(port, () => {
    console.log(` app is listening on port ${port}`)
})

前端Client代码(原问题代码)

import { useState, useEffect } from "react" 

const MainPage = () => {
    const [songList, setSongList] = useState([{}])
    const [currentSong, setCurrentsong] = useState({})

    useEffect(()=>
    {
        fetch("/songList")
            .then(response => response.json())
            .then(data => {setSongList(data)})
    },[])

    return(
        <div className="MainPageContiner">
            {console.log(typeof(songList))}  
        </div>
    )
}

export default MainPage

解决方案

核心问题原因

fs.readFileSync读取JSON文件后返回的是字符串类型,直接调用res.json(songList)会把这个字符串再做一次JSON序列化,导致后端返回的响应是一个包含整个JSON字符串的JSON值。客户端用response.json()解析后得到的依然是字符串,而非数组。

修改后端代码

将读取的字符串解析为JavaScript对象数组,再传给res.json():

const express = require('express')
const app = express()
const port = 5000
const fs = require('fs');

// 关键:把读取到的字符串解析为数组
const songList = JSON.parse(fs.readFileSync('data/songs.json', 'utf8'));

app.get("/songList",(req,res)=> 
{
    res.json(songList)
})

app.listen(port, () => {
    console.log(` app is listening on port ${port}`)
})

可选:优化前端初始状态

将songList的初始状态设为空数组,更符合实际场景:

const [songList, setSongList] = useState([])

验证效果

修改后,客户端fetch获取到的data会是数组类型,typeof songList会输出object(数组的类型本质是object),此时就可以正常使用.map方法渲染页面了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 15:05:13