Javascript 反应不';t在路由参数更改或查询更改时重新加载组件数据
我有一个带有链接的“主页”组件,当您单击链接时,产品组件将与产品一起加载。我还有一个始终可见的组件,显示“最近访问的产品”的链接 这些链接在产品页面上不起作用。当我单击链接时,url会更新,并进行渲染,但产品组件不会随新产品更新 请参见此示例: 以下是index.js中的路由:Javascript 反应不';t在路由参数更改或查询更改时重新加载组件数据,javascript,reactjs,react-router,react-router-v4,react-router-dom,Javascript,Reactjs,React Router,React Router V4,React Router Dom,我有一个带有链接的“主页”组件,当您单击链接时,产品组件将与产品一起加载。我还有一个始终可见的组件,显示“最近访问的产品”的链接 这些链接在产品页面上不起作用。当我单击链接时,url会更新,并进行渲染,但产品组件不会随新产品更新 请参见此示例: 以下是index.js中的路由: <BrowserRouter> <div> <Route exact path="/" render={props => <Ho
<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>;
}
/>
} />
} />
回家
;
ProductHistory中的链接如下所示:
<Link to={`/products/${product.product_id}`}> {product.name}</Link>
{product.name}
因此它们与路径=“/products/:product”
匹配
当我在产品页面上并尝试跟踪ProductHistory链接时,URL会更新并呈现,但组件数据不会更改。在Codesandbox示例中,您可以取消对Product components render函数中的警报的注释,以查看它在跟随链接时的渲染情况,但什么也没有发生
我不知道问题是什么……你能解释一下问题并找到解决办法吗?那太好了 由于产品组件已加载,因此不会重新加载。您必须使用下面的组件方法处理新产品id
componentWillReceiveProps(nextProps) {
if(nextProps.match.params.name.product == oldProductId){
return;
}else {
//fetchnewProduct and set state to reload
}
使用最新版本的react(16.3.0及以后版本)
除了
componentDidMount
,您还需要实现componentWillReceiveProps
或使用getDerivedStateFromProps
(从v16.3.0开始)在Products
页面中,由于使用更新的params
和未重新安装重新呈现相同组件,因此当您更改路由参数时,这是因为params作为道具传递给组件,并且在道具更改时,React组件重新呈现而未重新安装
编辑:来自v16.3.0,用于根据道具设置/更新状态(无需在两种不同的生命周期方法中指定)
在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
})
}
}
如果您不在组件中维护状态,则可以使用componentdiddupdate
,而无需getDerivedStateFromProps
:
componentDidUpdate(prevProps){
const{match:{params:{value}}}=this.props
if(prevProps.match.params.value!==值){
doSomething(this.props.match.params.value)
}
}
尽管上述所有方法都有效,但我认为使用getDerivedStateFromProps
没有任何意义。
根据React文档,“如果您只想在道具更改时重新计算某些数据,请改用备忘录辅助工具”
在这里,我建议只使用componentdiddupdate
,同时将组件更改为PureComponenet
对于React文档,PureComponenet
s仅在至少一个状态或属性值发生变化时才重新提交。通过对状态键和道具键进行粗略比较来确定更改
componentDidUpdate=(prevProps)=>{
if(this.props.match.params.id!==prevProps.match.params.id){
//基于获取新产品并将其设置为组件的状态
};
};代码>组件WillReceiveProps现在已不推荐使用。但是你还能怎么做呢?@BastianVoigt:你可以在react+16.3getDerivedStateFromProps
,componentdiddupdate
中使用新生命周期方法的集成,如中所述。我尝试了getDerivedStateFromProps
解决方案。但它不起作用。似乎getDerivedStateFromProps
仅在装载时触发一次。@arvinsim,不是真的,getDerivedStateFromProps在初始装载时以及在每次其他更新时都会触发。16.4版本中的API也发生了变化。我将更新我的答案,以纳入这一变化。这为我指明了正确的方向,感谢您的伟大回答。ComponentWillReceiveProps现在也被弃用并被认为是不安全的。。。还有其他方法吗?@BastianVoigt应该是prevProps,因为在props更改后将调用componentDidUpdate,这与我们在getDerivedStateFromProps中设置的下一步相同。对,但我希望在当前productID(this.props.productID)与我所在状态不同时重新加载,“你不这么认为吗?”巴斯蒂安沃伊特。对,这就是上述条件的作用。当前productID(this.props.producID)将有新的productID,我们在state变量中已经说过了。如果我们比较这一点,那么在我的情况下,它也适用于常规组件。在没有PureComponent
的情况下,它也适用于我,谢谢!
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;
}
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
})
}
}