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
相关产品推荐
相关产品推荐

