React Router-导航子路由时重新渲染父级

时间:2019-06-19 10:39:50

标签: reactjs react-router

如果我有一个根store组件,并且在其中嵌入了一个使用路由/product/:id渲染产品的product组件,则根/渲染每个根组件是否是正常行为?我何时更换产品?

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

使用此示例代码,每次从任何一个store更改为另一个/product/*时,根/product/*都会重新渲染。

是否存在一种建议的方法,以防止仅在更改子代时重新渲染根?

我正在使用react-router v5。您可以测试代码here

2 个答案:

答案 0 :(得分:0)

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


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

答案 1 :(得分:0)

您可以在 shouldComponentUpdate(可选)和 Store 组件中覆盖 Product 方法。如果您认为不应更新特定组件,则返回 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;
  }
...

我不知道为什么,但即使 ProductDetail 返回 Product.shouldComponentUpdatefalse 组件也会更新。我想这与 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;
});