React中从嵌套JSON获取数据并实现渲染展示的解决方案
问题描述
我正在开发一款可搜索并展示电影内容的Web应用,需要从同一接口返回的JSON数据中,同时获取外层对象(如title、year、runtime等)与嵌套对象(如principals)。目前已通过useEffect实现将principals数据渲染至AG Grid,但无法获取并展示title等外层数据。
接口返回的JSON数据:
{ "title": "The Match Factory Girl", "year": 1990, "runtime": 69, "genres": [ "Comedy", "Crime", "Drama" ], "country": "Finland, Sweden", "principals": [ { "id": "nm0653669", "category": "actress", "name": "Kati Outinen", "characters": [ "Iris Rukka" ] }, { "id": "nm0758825", "category": "actress", "name": "Elina Salo", "characters": [ "Mother" ] } ], "ratings": [ { "source": "Internet Movie Database", "value": 7.5 }, { "source": "Rotten Tomatoes", "value": null }, { "source": "Metacritic", "value": null } ], "boxoffice": 0, "poster": "https://m.media-amazon.com/images/M/MV5BMmM1ZTZhNDUtYzBkNi00YzQ0LWEyZjItM2M5OTI2ZTU0MDlkXkEyXkFqcGdeQXVyMjI0MjMwMzQ@._V1_SX300.jpg", "plot": "A woman's terribly dull life is upended by a one-night stand pregnancy, causing her to seek retribution." }
现有代码:
const [rowData, setRowData] = useState([]); const columns = [ {headerName: "Role", field: "role", sortable: true}, {headerName: "Name", field: "name"}, {headerName: "Characters", field: "characters"}, ]; useEffect(() => { fetch(`${API_URL}/movies/data/${imdbID}`) .then(res => res.json()) .then(people => people.principals) .then(principals => principals.map(person => { return { role: person.category, name: person.name, characters: person.characters, id: person.id } })) .then(allPeople => setRowData(allPeople)) .then(test => console.log("ss")) .catch(error => console.log(error)) }, []); return ( <div> <h1> The title of the movie is... </h1> <div className="ag-theme-balham" style={{height: "300px", width: "1100px"}}> <AgGridReact columnDefs={columns} rowData={rowData} pagination={true} paginationPageSize={7}/> </div> </div> )
解决方案
要同时获取外层电影数据和嵌套的principals数据,只需调整现有逻辑,先保留完整的接口响应数据,再分别处理:
步骤1:新增state存储电影外层信息
添加一个state来保存电影的基础信息:
const [movie, setMovie] = useState({});
步骤2:修改useEffect中的数据处理逻辑
不要直接跳过外层数据,先获取完整的响应对象,保存外层信息后再处理principals:
useEffect(() => { fetch(`${API_URL}/movies/data/${imdbID}`) .then(res => res.json()) .then(movieData => { // 先保存外层电影数据 setMovie(movieData); // 再处理principals数据 return movieData.principals; }) .then(principals => principals.map(person => ({ role: person.category, name: person.name, characters: person.characters.join(', '), // 可选:将数组转为字符串更友好展示 id: person.id })) ) .then(allPeople => setRowData(allPeople)) .catch(error => console.log(error)) }, [imdbID]); // 将imdbID加入依赖数组,确保参数变化时重新请求
步骤3:在JSX中展示外层电影数据
修改return部分,使用movie state中的数据展示标题、年份等信息:
return ( <div> <h1> The title of the movie is {movie.title} ({movie.year})</h1> <p>Runtime: {movie.runtime} mins | Genres: {movie.genres?.join(', ')}</p> <p>{movie.plot}</p> <div className="ag-theme-balham" style={{height: "300px", width: "1100px"}}> <AgGridReact columnDefs={columns} rowData={rowData} pagination={true} paginationPageSize={7}/> </div> </div> )
关键说明
- 通过先保存完整的
movieData到state,就能轻松访问所有外层属性 - 处理
characters时用join(', ')将数组转为字符串,避免AG Grid直接渲染数组的默认格式 - 将
imdbID加入useEffect的依赖数组,确保当电影ID变化时会重新发起请求获取对应数据
内容的提问来源于stack exchange,提问作者jcort
相关产品推荐
相关产品推荐

