React路由访问报错:Cannot read properties of undefined (reading 'pathname')
React Router动态路径访问报错:Cannot read properties of undefined (reading 'pathname')
我在App.js中配置了React Router路由,创建了movieState.js状态组件存储3个带不同URL的电影对象,但访问http://localhost:3000/work/bicycle这类动态路径时,触发"Cannot read properties of undefined (reading 'pathname')"错误。以下是相关代码:
App.js代码
//Styles import "./styles/app.scss"; //Global Style from styled-components import GlobalStyle from "./components/GlobalStyle"; //Router import { BrowserRouter as Router, Route, Routes } from 'react-router-dom'; //import Pages import AboutUs from './pages/AboutUs'; import OurWork from './pages/OurWork'; import ContactUs from './pages/ContactUs'; import MovieDetail from "./pages/MovieDetail"; //Nav component import Nav from './components/Nav'; function App() { return ( <div className="App"> <GlobalStyle /> <Nav /> <Routes> <Route path="/" element={<AboutUs />} /> <Route path="/work" element={<OurWork />} /> <Route path="/work/:id" element={<MovieDetail />} /> <Route path="/contact" element={<ContactUs />} /> </Routes> </div> ); } export default App;
movieState.js代码
//Import Images import { color } from "framer-motion"; import bicycle from "./img/bycicle.jpg"; import colorwall from "./img/colorwall.jpg"; import light from "./img/light.jpg"; export const MovieState = () => { return [ { title: "The Bicycle", mainImg: bicycle, secondaryImg: bicycle, url: "/work/bicycle", awards: [ { title: "Truly A masterpiece", description: "“Lorem Ipsum is simply dummy text of the printing and typesetting industry.”", }, { title: "Fresh look on a brutal sport.", description: "“Lorem Ipsum is simply dummy text of the printing and typesetting industry.”", }, { title: "It’s okay lmao.", description: "“Lorem Ipsum is simply dummy text of the printing and typesetting industry.”", }, ], }, { title: "The Color Wall", mainImg: colorwall, url: "/work/colorwall", secondaryImg: colorwall, awards: [ { title: "Truly A masterpiece", description: "“Lorem Ipsum is simply dummy text of the printing and typesetting industry.”", }, { title: "Fresh look on a brutal sport.", description: "“Lorem Ipsum is simply dummy text of the printing and typesetting industry.”", }, { title: "It’s okay lmao.", description: "“Lorem Ipsum is simply dummy text of the printing and typesetting industry.”", }, ], }, { title: "The Light", mainImg: light, url: "/work/light", secondaryImg: light, awards: [ { title: "Truly A masterpiece", description: "“Lorem Ipsum is simply dummy text of the printing and typesetting industry.”", }, { title: "Fresh look on a brutal sport.", description: "“Lorem Ipsum is simply dummy text of the printing and typesetting industry.”", }, { title: "It’s okay lmao.", description: "“Lorem Ipsum is simply dummy text of the printing and typesetting industry.”", }, ], }, ]; };
Nav.js代码
import React from 'react'; import styled from 'styled-components'; import { Link } from 'react-router-dom'; function Nav() { return ( <StyledNav> <Link to="/"> <h1>Logo</h1> </Link> <ul> <li><Link to="/" className='li'>About Us</Link></li> <li><Link to="/work" className='li'>Our Work</Link></li> <li><Link to="/contact" className='li'>Contact Us</Link></li> </ul> </StyledNav> ) }
MovieDetail.js代码
import React, { useEffect, useState } from 'react'; import { useNavigate } from 'react-router-dom'; import { MovieState } from '../movieState'; function MovieDetail() { const navigate = useNavigate(); const url = navigate.location.pathname; const [movies,setMovies] = useState(MovieState); const [movie,setMovie] = useState(null); //useEffect runs after the component is mounted useEffect(() => { const currentMovie = movies.filter((stateMovie) => stateMovie.url === url); setMovie(currentMovie); }, [movies,url]); return ( <div> <h1>Movie Detail</h1> </div> ) } export default MovieDetail;
问题修复方案
核心错误点
- 误用
useNavigate获取路径:useNavigate返回的是导航跳转函数,没有location属性,应该用useLocation钩子获取当前路由的location对象。 - 未调用
MovieState函数:原代码中useState(MovieState)只是把函数本身赋值给movies,需要调用MovieState()才能拿到数组数据。 filter使用不当:filter返回匹配的数组,而我们只需要单个电影对象,用find更合适。- 缺少空值判断:movie加载完成前为null,直接渲染会触发错误。
- App.js未用Router包裹所有路由组件:Nav和Routes必须在Router内部才能正常工作。
修复后的MovieDetail.js
import React, { useEffect, useState } from 'react'; import { useLocation } from 'react-router-dom'; import { MovieState } from '../movieState'; function MovieDetail() { const location = useLocation(); const url = location.pathname; const [movies, setMovies] = useState(MovieState()); const [movie, setMovie] = useState(null); useEffect(() => { const currentMovie = movies.find((stateMovie) => stateMovie.url === url); setMovie(currentMovie); }, [movies, url]); return ( <div> {movie ? <h1>{movie.title}</h1> : <h1>Loading...</h1>} </div> ) } export default MovieDetail;
修复后的App.js
//Styles import "./styles/app.scss"; //Global Style from styled-components import GlobalStyle from "./components/GlobalStyle"; //Router import { BrowserRouter as Router, Route, Routes } from 'react-router-dom'; //import Pages import AboutUs from './pages/AboutUs'; import OurWork from './pages/OurWork'; import ContactUs from './pages/ContactUs'; import MovieDetail from "./pages/MovieDetail"; //Nav component import Nav from './components/Nav'; function App() { return ( <Router> <div className="App"> <GlobalStyle /> <Nav /> <Routes> <Route path="/" element={<AboutUs />} /> <Route path="/work" element={<OurWork />} /> <Route path="/work/:id" element={<MovieDetail />} /> <Route path="/contact" element={<ContactUs />} /> </Routes> </div> </Router> ); } export default App;
内容的提问来源于stack exchange,提问作者Luis Alejandro Lopez de Anda
相关产品推荐
相关产品推荐

