我正在按照一个教程构建Django+React应用程序,他们使用React路由器v5,我使用v6.2.1(代码如下:https://github.com/linkedweb/realest_estate/blob/main/src/containers/ListingDetail.js)。
我想要一个PrivateRoute,用于验证用户呈现产品的详细信息。我试着调整代码,特别是根据这篇文章(React-TypeError:无法读取未定义的属性(读取';params';((,但我无法使其工作,我得到:
"未捕获的类型错误:无法读取未定义的属性(读取"params"(">
我尝试了很多变体,但这是我认为最接近正确的方法:
App.js
const App = () => (
<Provider store={store}>
<Router>
<Layout >
<Routes>
<Route exact path='/' element={<Home />} />
...
<Route exact path='/listings' element={<Listings/>} />
<Route path='/listings/:id' element={<PrivateRoute />}>
<Route path='' element= {<ListingDetail />}/>
</Route>
<Route path="*" element={<NotFound />} />
</Routes>
</Layout>
</Router>
</Provider>)
私有路由
const PrivateRoute = ({ auth: {isAuthenticated, loading }, ...rest }) => {
return (!isAuthenticated && !loading) ? (<Navigate to='/login' />) : (<Outlet {...rest}/>)}
PrivateRoute.propTypes = {
auth: PropTypes.object.isRequired};
const mapStateToProps = state => ({
auth: state.auth});
export default connect(mapStateToProps)(PrivateRoute);
上市详细信息
const ListingDetail = (props) => {
const [listing, setListing] = useState({});
useEffect(() => {
const slug = props.match.params.id;
const config = {
headers: {
'Authorization': `Bearer ${localStorage.getItem('token')}`}};
axios.get(`http://localhost:8000/api/listings/${slug}`, config)
.then(res => {
setListing(res.data);
})
.catch(err => { }); });
return (
<div className='listingdetail'>
<p>{listing.title}</p>
</div>
);};
export default ListingDetail;
我试图更改"const slug=props.match.params.id;"到'const{slug}=useParams((;',甚至在useEffect之外,但它没有起作用!
我可以做些什么来检索有关产品的数据并显示它们?
祝你今天愉快!
将path
道具移动到要渲染的Route
,希望路由组件访问的路由参数为(slug
(。
<Route element={<PrivateRoute />}>
<Route
path='/listings/:slug'
element= {<ListingDetail />}
/>
</Route>
ListingDetail
应该使用useParams
钩子来检索slug
路由参数。访问useEffect
钩子外部的slug
路由参数,并将slug
添加到useEffect
钩子的依赖数组中。
const ListingDetail = () => {
const { slug } = usePrams();
const [listing, setListing] = useState({});
useEffect(() => {
const config = {
headers: {
'Authorization': `Bearer ${localStorage.getItem('token')}`
},
};
axios.get(`http://localhost:8000/api/listings/${slug}`, config)
.then(res => {
setListing(res.data);
})
.catch(err => { });
}, [slug]);
return (
<div className='listingdetail'>
<p>{listing.title}</p>
</div>
);
};