React Router - 导航子路由时父组件会重新渲染

3
如果我有一个根store组件,并在其中嵌入一个产品组件,该组件使用路由/product/:id呈现产品,那么每次我更改产品时,根/渲染是正常行为吗?
import React, {Component} from "react";
import ReactDOM from "react-dom";

import { BrowserRouter, Route, Link } from "react-router-dom";


const Products = [
  { "id" : "First", info : "Great product"},
  { "id" : "Second", info : "Another Great product"},
  { "id" : "Third", info : "Some other product"},
  { "id" : "Fourth", info : "Worst product"},
]

class ProductDetail extends Component {
  render(){
    console.log("rendering ProductDetail");
    const {match} = this.props;
    const product = Products.find(({id}) => id === match.params.productId);
    return <div>
      <h3>{product.id}</h3>
      <span>{product.info}</span>
    </div>
  }
}

class Product extends Component {
  render(){
  console.log("rendering Product");
    const {match} = this.props;
    return <div>
      <h2>This shows the products</h2>
      <ul>
        {Products.map(p=><li><Link to={`${match.url}/${p.id}`}>{p.id}</Link></li>)}
      </ul>
      <Route path={`${match.path}/:productId`} component={ProductDetail}/>
    </div>
  }
}

class Store extends Component {
   render(){
  console.log("rendering Store");
     const {match} = this.props;
     return <div>
       <h1>This is the Store</h1>
        <Link to={`${match.url}product`}>See products</Link>
       <Route path={`${match.path}product`} component={Product}/>
     </div>
   }
}

function App() {
  console.log("rendering App");
  return (
    <div className="App">
      <BrowserRouter>
        <Route path="/" component={Store}/>
      </BrowserRouter>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

使用此示例代码,每次从任何/product/*切换到另一个/product/*时,根store将重新呈现。
是否有建议的方法可以防止根节点在只更改子节点时重新呈现?
我正在使用react-router v5。 您可以在此处测试代码。

这个问题已经在这里提出了:“https://dev59.com/31YM5IYBdhLWcg3w1Cvx?rq=1”,但是答案与上面的代码不兼容。 - Victor.dMdB
你有没有找到解决这个问题的方法? - Elliot B.
2个回答

0
你可以在 Store(可选)和 Product 组件中重写 shouldComponentUpdate 方法。如果你认为特定的组件不应该被更新,返回 false
class Product extends Component {
  shouldComponentUpdate(nextProps, nextState) {
    // Make your own comparisons (returning false will do the trick for your case)
    return false;
  }
...

class Store extends Component {
  shouldComponentUpdate(nextProps, nextState) {
    // Make your own comparisons (returning false will do the trick for your case)
    return false;
  }
...

我不确定为什么,但是即使Product.shouldComponentUpdate返回falseProductDetail组件也会被更新。我猜这与ProductDetailRoute组件的一部分有关...

对于Hooks,您可以像这样使用React.memo:

const Store = React.memo((props) => {
   ...
}, (prevProps, nextProps) => {
  // Comment below is from React documentation.
  /*
   return true if passing nextProps to render would return
   the same result as passing prevProps to render,
   otherwise return false
  */
  return true;
});

0
<BrowserRouter>
    <Route exact path="/" component={Store}/>
  </BrowserRouter>


 // I think its solve your issue add 'exact'

2
这意味着所有嵌套路由都无法渲染。您可以在此处进行测试 https://codesandbox.io/embed/blissful-morse-c7r6f - Victor.dMdB

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接