如何在React.js中使用useEffect、useState Hooks调用API并结合map函数渲染数据
问题修正与修改方案
核心错误点
- 状态使用混淆:
setMovieData是状态更新函数,不能用来读取数据,存储接口返回数据的是状态变量movieData - 状态更新语法错误:更新状态需要执行函数
setMovieData(要更新的值),不能直接用等于号赋值 - 未遍历数组渲染:
movieData是数组类型,无法直接读取对象属性,你推测的用map遍历生成Card的思路完全正确 - 字段名不匹配:TMDB接口返回的对应字段为
original_title、poster_path、release_date,你使用的自定义字段名不存在 - 列表渲染未加唯一key:遍历生成组件需要添加key属性避免React运行警告
修改后的完整代码
import React, { useEffect, useState } from "react"; import { Button, Card, CardActionArea, CardActions, CardContent, CardMedia, Typography } from "@material-ui/core"; const cardStyle = { cardMain: { maxWidth: "300px", margin: "10px", }, cardImage: { height: "150px", marginLeft: "7px", marginRight: "7px", marginTop: "5px", }, }; // 修正原组件拼写错误,改为符合业务场景的命名 const Movies = () => { const [movieData, setMovieData] = useState([]); const [loading, setLoading] = useState(true); const getMovieList = async () => { const url = "http://api.themoviedb.org/3/search/movie?api_key=myapikey&query=Avengers"; try { const response = await fetch(url); const responseJson = await response.json(); // 正确调用状态更新函数 setMovieData(responseJson.results || []); setLoading(false); } catch (err) { console.error(err); setLoading(false); } }; useEffect(() => { getMovieList(); }, []); if (loading) return <div>加载中...</div>; return ( <div style={{display: 'flex', flexWrap: 'wrap', padding: '20px'}}> {/* 遍历数组生成每个电影对应的Card组件 */} {movieData.map(movie => ( <Card key={movie.id} style={cardStyle.cardMain}> <CardActionArea> <Typography gutterBottom variant="h6" component="h3" style={{padding: '0 7px', marginTop: '10px'}}> {movie.original_title} </Typography> <CardMedia style={{ ...cardStyle.cardImage, backgroundImage: `url(https://image.tmdb.org/t/p/w500${movie.poster_path})` }} /> <CardContent> <Typography variant="body2" color="textSecondary"> 上映日期:{movie.release_date} </Typography> </CardContent> </CardActionArea> <CardActions> <Button size="small" color="primary">Watch</Button> <Button size="small" color="primary">Like</Button> <Button size="small" color="primary">Rent</Button> </CardActions> </Card> ))} </div> ); }; export default Movies;
补充说明
- 外层新增flex布局让卡片自动换行排列,你可以根据自身需求调整布局样式
- 增加了加载状态,避免接口请求过程中页面出现空白
- 所有字段都和TMDB官方返回的字段做了匹配,确保可以正常读取数据
内容的提问来源于stack exchange,提问作者Tapesh Patel
相关产品推荐
相关产品推荐

