如果我有一个根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
答案 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.shouldComponentUpdate
,false
组件也会更新。我想这与 ProductDetail
是 Route
组件的一部分有关...
对于 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;
});