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

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

问题描述

我有一个带有链接的主页"组件,当您单击链接时,产品组件会与产品一起加载.我还有另一个始终可见的组件,显示最近访问过的产品"的链接.

这些链接在产品页面上不起作用.单击链接时 url 会更新,并且会发生渲染,但产品组件不会随新产品一起更新.

看这个例子:Codesandbox 示例

这里是 index.js 中的路由:

<div><路线精确的路径=/"渲染={道具=><家居产品={this.state.products}/>}/><Route path="/products/:product" render={props =><产品{...道具}/>}/><Route path="/" render={() =><ProductHistory/>}/><Link to="/">到首页</Link>

</BrowserRouter>;

ProductHistory 中的链接如下所示:

{product.name}

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

当我在产品页面上并尝试遵循 ProductHistory 链接时,URL 会更新并呈现,但组件数据不会更改.在 Codesandbox 示例中,您可以取消注释 Product components render function 中的警报,以查看当您点击链接时它会呈现,但没有任何反应.

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

解决方案

componentDidMount 一起,您还需要实现 componentWillReceiveProps 或使用 getDerivedStateFromProps(从 v16.3.0 开始)在 Products 页面中,因为相同的组件是 re-rendered 与更新的 paramsnot re-mounted 当您更改路由参数时,这是因为 params 作为 props 传递给组件,并且在 props 更改时,React 组件重新渲染而不是重新安装.

从 v16.3.0 使用 getDerivedStateFromProps 根据 props 设置/更新状态(无需在两种不同的生命周期方法中指定)

static getDerivedStateFromProps(nextProps, prevState) {if (nextProps.match.params.product !== prevState.currentProductId){const currentProductId = nextProps.match.params.productconst 结果 = productlist.products.filter(obj => {返回 obj.id === currentProductId;})返回 {产品:结果[0],当前ID:当前产品ID,结果}}返回空;}

在 v16.3.0 之前,您将使用 componentWillReceiveProps

componentWillReceiveProps(nextProps) {if (nextProps.match.params.product !== this.props.match.params.product) {const currentProductId = nextProps.match.params.productconst 结果 = productlist.products.filter(obj => {返回 obj.id === currentProductId;})this.setState({产品:结果[0],当前ID:当前产品ID,结果})}}

工作代码和盒子

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 or use getDerivedStateFromProps(from v16.3.0 onwards) 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.

EDIT: from v16.3.0 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;
}

Prior v16.3.0, you would use 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

      })
    }
  }

Working codesandbox

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

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