React项目中TypeError: Cannot read properties of undefined (reading 'map')问题求助
问题描述
我在React项目中遇到了TypeError错误,当使用watchlist.map时提示“Cannot read properties of undefined (reading 'map')”。
我的app.js初始化和组件调用代码如下:
function App() { const [movies, setMovies] = useState([]); const [watchlist, setWatchlist] = useState([]); useEffect(() => { fetch("movies.json") .then((response) => response.json()) .then((data) => setMovies(data)); }, []); const toggleWatchlist = (movieId) => { setWatchlist((prev) => prev.includes(movieId) ? prev.filter((id) => id !== movieId) : [...prev, movieId] ); }; return ( <div className="App"> <div className="container"> <Header></Header> <Router> <nav> <ul> <li> <Link to="/">Home</Link> </li> <li> <Link to="/watchlist">Watchlist</Link> </li> </ul> </nav> <Routes> <Route path="/" element={ <MoviesGrid movies={movies} watchlist={watchlist} toggleWatchlist={toggleWatchlist} /> } ></Route> <Route path="/watchlist" element={ <WatchList movies={movies} watchlist={watchlist} toggleWatchlist={toggleWatchlist} /> } ></Route> </Routes> </Router> </div> <Footer></Footer> </div> ); } export default App;
我的WatchList组件代码:
export default function WatchList(movies, watchlist, toggleWatchlist) { return ( <div> <h1 className="title">Your Watchlist</h1> <div className="watchlist"> {watchlist.map((id) => { const movie = movies.find((movie) => movie.id === id); return ( <MovieCard key={id} movie={movie} toggleWatchlist={toggleWatchlist} isWatchlisted={true} ></MovieCard> ); })} </div> </div> ); }
使用watchlist.map时出现如下错误:
TypeError: Cannot read properties of undefined (reading 'map')
虽然我在DevTools里看到watchlist是包含2个元素的数组,但组件就是无法渲染电影卡片。
我已经尝试过这些方法但都没用:
- 修改了watchlist参数的名称
- 在
watchlist.map前添加watchlist &&判断
明明useState已经初始化了空数组,为什么watchlist还是undefined呢?
解决方案
兄弟,问题出在你WatchList组件接收props的方式上!
React函数组件的所有props都是以单个对象的形式传入的,不是像你现在这样拆成多个独立参数来接收。你当前的写法:
export default function WatchList(movies, watchlist, toggleWatchlist) { // ... }
这里的第一个参数movies其实是整个props对象,而watchlist、toggleWatchlist这两个参数根本没有被传入任何值——React只会给组件传第一个参数(props对象),所以它们自然都是undefined。这就是为什么你用watchlist.map时会触发“读取undefined的map属性”的错误。
正确的写法:解构props对象
你只需要把组件的参数改成解构props的形式,就能正确拿到传入的值了:
export default function WatchList({ movies, watchlist, toggleWatchlist }) { return ( <div> <h1 className="title">Your Watchlist</h1> <div className="watchlist"> {watchlist.map((id) => { const movie = movies.find((movie) => movie.id === id); return ( <MovieCard key={id} movie={movie} toggleWatchlist={toggleWatchlist} isWatchlisted={true} ></MovieCard> ); })} </div> </div> ); }
通过{ movies, watchlist, toggleWatchlist }的解构语法,我们从props对象中提取出需要的三个属性,这样组件内部就能正确访问到App传过来的watchlist数组,map方法也能正常工作了。
额外说明
你在DevTools里看到的是App组件中的watchlist状态有值,但这并不代表WatchList组件正确接收到了这个值——因为组件接收参数的方式错误,导致内部的watchlist还是undefined。修改完参数写法后,你的电影卡片应该就能正常渲染啦!
备注:内容来源于stack exchange,提问作者William Monahan

