React-Router:嵌套路由和父重新渲染

时间:2018-01-18 06:13:23

标签: reactjs react-router

我正在使用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)重新渲染?谢谢你的帮助!

3 个答案:

答案 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>
    );
}
相关问题