React不会在路由参数更改或查询更改时重新加载组件数据 [英] React doesn't reload component data on route param change or query change

查看:152
本文介绍了React不会在路由参数更改或查询更改时重新加载组件数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有链接的home组件,当您单击链接时,产品组件随产品一起加载。我还有另一个始终可见的组件,显示最近访问过的产品的链接。



这些链接在产品页面上不起作用。单击链接时会更新URL,并且会进行渲染,但产品组件不会使用新产品进行更新。



请参阅此示例:
Codesandbox示例



以下是索引中的路线.js:

 < BrowserRouter> 
< div>
< Route
完全
path =/
render = {props => < Home products = {this.state.products} />}
/>

< Route path =/ products /:productrender = {props => < Product {... props} />} />

< Route path =/render = {()=> < ProductHistory />} />

< Link to =/> to Home< / Link>
< / div>
< / BrowserRouter> ;;

ProductHistory中的链接如下所示:

 < Link to = {`/ products / $ {product.product_id}`}> {product.name}< /链接> 

所以它们匹配 Route path =/ products /:product



当我在产品页面上并尝试关注ProductHistory链接时,会更新URL并进行渲染,但组件数据不会不要改变。在Codesandbox示例中,您可以取消注释产品组件呈现功能中的警报,以便在您按照链接时看到它呈现,但没有任何反应。



我不知道是什么问题是......你能解释一下问题并找到解决方案吗?那太好了!

解决方案

除了 componentDidMount ,你还需要在产品页面中实现 componentWillReceiveProps 功能,因为同一个组件重新呈现更新了 params 并且没有重新安装当你改变路线参数时,这是因为params作为道具传递到组件并在道具上更改,React组件重新渲染而不是重新安装。

  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({

产品:结果[0],
currentId:currentProductId,
结果

})
}
}

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;

})
返回{

产品:结果[0],
currentId:currentProductId,
结果

}
}
返回null;
}


I have a "home" component with links, and when you click a link the product component is loaded with the product. I also have another component which is always visible, showing links to the "recently visited products".

These links don't work when on a product page. The url updates when I click the link, and a render occurs, but the product component doesn't update with the new product.

See this example: Codesandbox example

Here are the routes in 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>;

The links in ProductHistory look like this:

<Link to={`/products/${product.product_id}`}> {product.name}</Link>

So they match the Route path="/products/:product".

When I am on a product page and try to follow a ProductHistory link, the URL updates and a render occurs, but the component data doesn't change. In the Codesandbox example you can uncomment the alert in Product components render function to see that it renders when you follow the link, but nothing happens.

I don't know what the problem is...Can you explain the problem and find a solution? That would be great!

解决方案

Along with componentDidMount, You also need to implement the componentWillReceiveProps function in Products page since the same component is re-rendered with updated params and not re-mounted when you change the route params, this is because params are passed as props to the component and on props change, React components re-render and not re-mounted.

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

      })
    }
  }

Working codesandbox

With the latest version of React(v16.3.0 onwards) you can use getDerivedStateFromProps to set/update state based on props(no need to specify it in two different lifecyle methods)

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;
}

这篇关于React不会在路由参数更改或查询更改时重新加载组件数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆