Gal*_*van 19 javascript reactjs react-router react-router-v4 react-router-dom
我有一个带有链接的"主页"组件,当您单击链接时,产品组件将随产品一起加载.我还有另一个始终可见的组件,显示"最近访问过的产品"的链接.
这些链接在产品页面上不起作用.单击链接时会更新URL,并且会进行渲染,但产品组件不会使用新产品进行更新.
请参阅此示例: Codesandbox示例
以下是index.js中的路由:
<BrowserRouter>
<div>
<Route
exact
path="/"
render={props => <Home products={this.state.products} />}
/>
<Route path="/products/:product" render={props => <Product {...props} />} />
<Route path="/" render={() => <ProductHistory />} />
<Link to="/">to Home</Link>
</div>
</BrowserRouter>;
Run Code Online (Sandbox Code Playgroud)
ProductHistory中的链接如下所示:
<Link to={`/products/${product.product_id}`}> {product.name}</Link>
Run Code Online (Sandbox Code Playgroud)
所以他们匹配Route path="/products/:product".
当我在产品页面上并尝试关注ProductHistory链接时,会更新URL并进行渲染,但组件数据不会更改.在Codesandbox示例中,您可以取消注释Product components render function中的警报,以便在您按照链接时看到它呈现,但没有任何反应.
我不知道问题是什么......你能解释一下问题并找到解决办法吗?那太好了!
Shu*_*tri 30
除此之外componentDidMount,您还需要在页面中实现componentWillReceiveProps或使用getDerivedStateFromProps(从v16.3.0开始),Products因为相同的组件已re-rendered 更新params,not re-mounted当您更改路径参数时,这是因为参数作为道具传递给组件并且在道具上更改,React组件重新渲染,而不是重新安装.
编辑:从v16.3.0用于getDerivedStateFromProps基于道具设置/更新状态(无需在两种不同的生命周期方法中指定它)
static getDerivedStateFromProps(nextProps, prevState) {
if (nextProps.match.params.product !== prevState.currentProductId){
const currentProductId = nextProps.match.params.product
const result = productlist.products.filter(obj => {
return obj.id === currentProductId;
})
return {
product: result[0],
currentId: currentProductId,
result
}
}
return null;
}
Run Code Online (Sandbox Code Playgroud)
在v16.3.0之前,您将使用componentWillReceiveProps
componentWillReceiveProps(nextProps) {
if (nextProps.match.params.product !== this.props.match.params.product) {
const currentProductId = nextProps.match.params.product
const result = productlist.products.filter(obj => {
return obj.id === currentProductId;
})
this.setState({
product: result[0],
currentId: currentProductId,
result
})
}
}
Run Code Online (Sandbox Code Playgroud)
由于产品组件已加载,因此不会重新加载.您必须在以下组件方法中处理新产品ID
componentWillReceiveProps(nextProps) {
if(nextProps.match.params.name.product == oldProductId){
return;
}else {
//fetchnewProduct and set state to reload
}
Run Code Online (Sandbox Code Playgroud)
随着最新版本的反应(16.3.0起)
static getDerivedStateFromProps(nextProps, prevState){
if(nextProps.productID !== prevState.productID){
return { productID: nextProps.productID};
}
else {
return null;
}
}
componentDidUpdate(prevProps, prevState) {
if(prevProps.productID !== this.state.productID){
//fetchnewProduct and set state to reload
}
}
Run Code Online (Sandbox Code Playgroud)
尽管上述所有方法都有效,但我认为没有必要使用getDerivedStateFromProps. 基于 React 文档,“如果您想仅在 prop 更改时重新计算某些数据,请改用 memoization helper”。
在这里,相反,我建议简单地使用componentDidUpdate并更改Componentto PureComponenet。
参考 React 文档,PureComponenet只有在至少一个 state 或 prop 值发生变化时才重新渲染。更改是通过对 state 和 prop 键进行浅层比较来确定的。
componentDidUpdate = (prevProps) => {
if(this.props.match.params.id !== prevProps.match.params.id ) {
// fetch the new product based and set it to the state of the component
};
};Run Code Online (Sandbox Code Playgroud)
请注意,以上仅当您将 Component 更改为 PureComponent 时才有效,显然,您需要从 React 导入它。
| 归档时间: |
|
| 查看次数: |
23369 次 |
| 最近记录: |