[英]React Router <Link> and <Route> not passing state to Component
React Router:链接和路由不将状态传递给组件
我正在使用 React、Redux 和 React Router 构建一个在线购物应用程序。 在主页上,显示所有项目。 我希望用户能够单击图像并被带到包含该项目的项目详细信息的页面。
这是我尝试这样做的方法:
这看起来很简单,我在 SO 和网络上看到了很多关于这个的讨论。 以下是我已经尝试过的一些:
单击 React Router 中的 Link 后显示项目详细信息
通过 React-Router v4 <Link /> 传递值
Tyler McGinnis - 将道具传递给 React Router 的 Link 组件
Medium - 如何将 props 传递给 React 路由组件
我能够获取要更改的 URL 以对应于项目的 ID,但我无法让 Item 组件以正确的信息呈现,有时我会根据我使用的方法出现错误。 我在 Item.js 的 div 中硬编码了“Item Component”这个词,当我点击主页上的图像时,它就会呈现出来。 否则,什么都不会渲染或我收到以下两个TypeErrors:
应用程序.js:
<Route path="/products" render={(props) => (<Item {...props} id={this.props.location.id} />) }/>
export default withRouter(App);
<App />
被包裹在 index.js 的<BrowserRouter>
中。
单击主页上的图像时,我收到以下错误:
类型错误:无法读取未定义的属性“道具”
当从上面的“渲染”代码中删除并替换为“component={ Item }”时,我从 Item.js 收到此错误: TypeError:无法读取未定义的属性“位置”
这是我的其他代码片段:
项目.js:
class Item extends React.Component {
constructor() {
super();
this.state = {
item: this.props.location.state
}
}
render() {
let item = this.state.item;
return (
<div className="item" key={item.id}>
<div className="item-image">
<img src={item.img} alt={item.title} />
</div>
<div className="card-component">
<span className="item-title">{item.title}</span>
<p className="item-price"><b>${item.price}</b></p>
<p className="item-desc">{item.desc}</p>
</div>
</div>
);
}
}
Home.js (显示所有项目),项目详细信息页面的链接如下:
<Link to =
{{ pathname: `/products/${item.category}`,
search: `?id=${item.id}`,
state: {id: `${item.id}`} }}
component={ Item }>
<img src={item.img} alt={item.title} />
</Link>
更新
我已经将<Item/>
组件包装在withRouter()
。 在 Item.js 中,如果我将构造函数中的状态设置为{ item: this.props.location.state }
,则不会呈现任何内容(屏幕上只有一个美元符号,因为价格部分包含硬编码的美元标志)。
我尝试在构造函数中将 Item.js 状态设置为null
,然后在componentDidMount()
使用{ item: this.props.location.state }
调用this.setState
。 当我这样做时,我收到以下错误:
类型错误:无法读取 null 的属性“img”
另外,如果我在App.js
的<Route>
中保留render={(props) => (<Item {...props} id={this.props.location.id} />) }
,我会收到这个错误:
类型错误:无法读取未定义的属性“道具”
如果我将<Route>
改回component={ Item }
,并且 Item.js 构造函数状态设置为{ item: this.props.location.state }
,则只会呈现美元符号。
更新:包括 App.js 和 Routes.js 代码
应用程序.js
import React from 'react';
import {
BrowserRouter as Router,
withRouter,
Switch
} from 'react-router-dom';
import './App.css';
import Navbar from './components/Navbar';
import Footer from './components/footer/Footer';
import { Routes } from './constants/Routes';
class App extends React.Component {
render() {
return (
<Router>
<div className="App">
<Navbar />
<Switch>
{ Routes }
</Switch>
<Footer />
</div>
</Router>
);
}
}
export default withRouter(App);
路由.js
import React from 'react';
import { Route } from 'react-router-dom';
import Home from '../components/Home';
import Item from '../components/shopping/Item';
import Cart from '../components/cart/Cart';
import OrderStatus from '../components/footer/OrderStatus';
import GiftCards from '../components/footer/GiftCards';
import ReturnsExchanges from '../components/footer/Returns-Exchanges';
import Contact from '../components/footer/Contact';
export const Routes = <div>
<Route exact path="/" component={ Home } />
<Route path="/products" component={ Item }/>
<Route path="/cart" component={ Cart } />
<Route path="/order-status" component={ OrderStatus } />
<Route path="/gift-cards" component={ GiftCards } />
<Route path="/returns-exchanges" component={ ReturnsExchanges } />
<Route path="/contact" component={ Contact } />
</div>
在任何组件中访问history
对象属性的一种方法是,您需要使用withRouter
包装该组件。 从react-router-dom
导入withRouter
并像这样包装你的App
组件:
export default withRouter(App);
更多关于withRouter 。
此外,在index.js
,确保您的<App />
被包裹在<BrowserRouter>
。
import { BrowserRouter } from 'react-router-dom';
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>
, document.getElementById('root'));
编辑:
类型错误:无法读取未定义的属性“道具”
将您的constructor
替换为以下代码。 当为 React 组件实现构造函数时, super(props)
应该在任何其他语句之前,否则构造函数中的 props 将是undefined
的。
constructor(props){
super(props);
this.state = {
item: this.props.location.state
}
}
错误:类型错误:无法读取 null 的属性“img”
原因:状态的初始值不应为null
。 在这种情况下,您可以传递空对象{}
但不能传递 null。 你试图访问img
, title
, price
及desc
在Item.js
但只有通过id
在state
的<Link>
在Home.js
。
<Link to =
{{ pathname: `/products/${item.category}`,
search: `?id=${item.id}`,
state: {id: `${item.id}`} //pass img, title, desc, price etc as well
}}
component={ Item }>
<img src={item.img} alt={item.title} />
</Link>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.