React应用调用REST API获取数据展示异常问题排查
React电影选择功能修复方案

你的现有代码存在几处逻辑错误,按以下步骤修改即可实现选中影片展示对应URL的需求:
现存问题
- 缺少选中影片的独立状态存储,下拉选择框没有绑定值变更事件,用户选择的操作无法被组件感知
<select>标签的value绑定错误:movies是接口返回的数组对象,不存在movies.title属性,会导致下拉选择功能完全失效- 当前代码遍历渲染了全部电影的链接,没有做选中项匹配,无法实现“选中哪条展示哪条”的效果
- 接口地址行混入了无效的markdown标记,会引发语法报错
- 未显式导入
useState、useEffect依赖,运行时会直接报钩子未定义的错误
修改步骤
- 新增选中电影ID的状态,在原有state声明区域添加:
const [selectedMovieId, setSelectedMovieId] = useState(null);
- 清理接口地址行的无效内容,将混入乱码的接口地址声明修正为:
const url = "http://localhost:8900/movies";
- 重写下拉选择框代码,绑定正确的value和变更事件,给列表项补充React要求的key属性:
<select value={selectedMovieId ?? ""} onChange={(e) => setSelectedMovieId(Number(e.target.value))} > <option value="" disabled>请选择影片</option> {movies.map(movie => ( <option key={movie.id} value={movie.id}> {movie.title} </option> ))} </select>
- 替换原有的全量电影列表渲染逻辑,改为根据选中ID匹配对应影片,仅展示选中项的URL:
{selectedMovieId && ( <div> <p>已选中:{movies.find(m => m.id === selectedMovieId).title}</p> <p>影片地址:<a href={movies.find(m => m.id === selectedMovieId).url}> {movies.find(m => m.id === selectedMovieId).url} </a></p> </div> )}
完整修改后的Movies.js代码
import { useState, useEffect } from 'react'; export default function Movies() { const [error, setError] = useState(null); const [isLoaded, setIsLoaded] = useState(false); const [movies, setMovies] = useState([]); const [selectedMovieId, setSelectedMovieId] = useState(null); const url = "http://localhost:8900/movies"; useEffect(() => { fetch(url) .then(res => res.json()) .then( (result) => { setIsLoaded(true); setMovies(result); }, (error) => { setIsLoaded(true); setError(error); } ) }, []) if (error) { return <div>Error: {error.message}</div>; } else if (!isLoaded) { return <div>Loading...</div>; } else { const selectedMovie = movies.find(m => m.id === selectedMovieId); return ( <div> <select value={selectedMovieId ?? ""} onChange={(e) => setSelectedMovieId(Number(e.target.value))} > <option value="" disabled>请选择影片</option> {movies.map(movie => ( <option key={movie.id} value={movie.id}> {movie.title} </option> ))} </select> {selectedMovie && ( <div style={{marginTop: '1rem'}}> <p>选中影片:{selectedMovie.title}</p> <p>对应链接:<a href={selectedMovie.url}>{selectedMovie.url}</a></p> </div> )} </div> ); } }
注意事项
启动json-server时如果要使用8900端口,需要在启动命令中指定端口参数,完整命令为json-server --watch test.json --port 8900,否则服务默认会运行在3000端口,导致前端请求接口失败。
内容的提问来源于stack exchange,提问作者New CS Developer
相关产品推荐
相关产品推荐

