我正在使用react-router v4,并且在嵌套路由方面遇到了一些麻烦。我的父路由是一个产品详细信息页面,它使用componentDidMount()中的AJAX请求来设置产品数据。
但是,当我点击链接以呈现嵌套在详细信息页面中的路由时,父路由会重新呈现并再次执行AJAX请求吗?
以下是一些快速示例代码:
const App = () => (
<Router>
<Switch>
<Route path="/login" component={LoginPage} />
<Route path="/admin" component={AdminPage} />
</Switch>
</Router>
)
const AdminPage = ({match}) => (
<Switch>
<Route exact path={match.path} component={Home} />
<Route path={`${match.path}/products/:id`} component={ProductDetails} />
<Route path={`${match.path}/products`} component={ProductList} />
</Switch>
)
class ProductDetails extends React.Component {
constructor(){
super();
this.state = {
name: '',
price: ''
};
}
componentDidMount(){
API.getProductDetails((response) => {
this.setState({
name: response.name,
price: response.price
});
})
}
render(){
return(
<div>
<h1>{this.state.name}</h1>
<p>{this.state.price}</p>
<ul>
<li><Link to={`${this.props.match.url}/stats}>Stats</Link></li>
<li><Link to={`${this.props.match.url}/bids}>Bids</Link></li>
<li><Link to={`${this.props.match.url}/third}>Third</Link></li>
</ul>
<Switch>
<Route path={`${this.props.match.path}/stats} component={Stats} />
<Route path={`${this.props.match.path}/bids} component={Bids} />
<Route path={`${this.props.match.path}/third} component={Third} />
</Switch>
</div>
);
}
}
那么当我打开其中一个嵌套的路由时,如何阻止父组件(ProductDetails)重新渲染?谢谢你的帮助!
答案 0 :(得分:1)
就我而言,使用render
道具代替component
并不能解决这个问题。
我的问题是关于HOC的,我必须将其从路由中删除:
<Route path="/:locale" render={({ match: { url } }) => (
<Switch>
<Route exact
path={`${url}/login`}
component={hocCausingIssue(LoginPage)}
/>
</Switch>
)}
/>
蜜饯:
<Route path="/:locale" render={({ match: { url } }) => (
<Switch>
<Route exact
path={`${url}/login`}
component={LoginPage}
/>
</Switch>
)}
/>
// LoginPage
export default hocCausingIssue(LoginPage) // Now it no longer causes issue
答案 1 :(得分:0)
我有一个类似的问题,当尝试从子组件调用Redirect时,整个父组件都在被重建。 https://about.gitlab.com/pricing/#self-managed,希望对您有所帮助!
tl; dr:尝试更改应用的路线以使用渲染代替组件。
const App = () => (
<Router>
<Switch>
<Route path="/login" render={() => <LoginPage />}
<Route path="/admin" render={() => <AdminPage />}
</Switch>
</Router>
)
答案 2 :(得分:0)
重新渲染父级似乎是 React 的预期行为。
对于只执行一次 AJAX 请求的情况,您应该寻找的一种替代方法是在父组件挂载时执行它,这种情况只发生一次。
例如,使用功能组件:
function Route() {
return (
<Route path="/main" render={() => <Main/>} />
);
}
function Main() {
useEffect(() => {
console.log("Main mounted");
// execute ajax here
}, []) // this empty dependency array turns it into a "componentDidMount" effect
return (
<div>
<h1>Main</h1>
<Route exact path="/main/tab1" render={() => <Tab1/>}/>
<Route exact path="/main/tab2" render={() => <Tab2/>}/>
</div>
);
}
function Tab1() {
return (
<div>Tab1</div>
);
}
function Tab2() {
return (
<div>Tab2</div>
);
}