【问题标题】:Nesting relative routes with react-router使用 react-router 嵌套相对路由
【发布时间】:2017-11-01 03:33:38
【问题描述】:

我有一个类别索引页面,该页面链接到特定于该类别的产品的产品索引页面。这么多在起作用。但是,当我尝试单击链接到特定于该产品的显示组件的产品时,我遇到了麻烦。以下是我的代码:

路由器.js

import React from 'react';
import { Router, Route, Switch } from 'react-router';
import createBrowserHistory from 'history/createBrowserHistory'
import App from './App';
import CategoriesIndexPage from './pages/categories/CategoriesIndexPage';
import ProductsIndexPage from './pages/products/ProductsIndexPage';
import ProductShow from './pages/products/ProductShow';
import LocationsPage from './pages/LocationsPage';

const history = createBrowserHistory()

const router = (
  <Router history={history}>
    <Switch>
      <Route exact path='/' component={App}/>
      <Route path='/categories' component={CategoriesIndexPage}/>
      <Route path='/locations' component={LocationsPage}/>
      <Route path='/:category' component={ProductsIndexPage}>
        <Route path='/:id' component={ProductShow}/>
      </Route>
    </Switch>
  </Router>
);

export default router;

ProductIndexPage.js

import React, { Component } from 'react';
import { BWReactData } from '../../config/FirebaseConstants.js';
import Head from '../../components/Head.js';
import Foot from '../../components/Foot.js';
import ProductsIteration from './ProductsIteration';

class ProductsIndexPage extends Component {
  constructor(props){
    super(props);
    this.state = {
      allProducts: [],
      loading: true,
    }
  }

  componentDidMount() {
    ...
  }

  render() {
    let allProducts = this.state.allProducts;
    let loading = this.state.loading;
    let categoryURL = this.props.location.state.category;


    return (
      <div>
      <Head/>
      <ProductsIteration
        allProducts={allProducts}
        loading={loading}
        categoryURL={categoryURL}
      />
      <Foot/>
      </div>
    )
  }
}

export default ProductsIndexPage;

ProductsIteration.js

import React from 'react';
import { Link } from 'react-router-dom';
import { Col, Row } from 'react-materialize';

const ProductsIteration = props => {
  let category = props.categoryURL;

  if (props.loading) {
    return <div>Loading...</div>
  }
  return (
    <Row>
    {props.allProducts.map(function(object) {
      return (
        <Col s={12} m={6} l={3} key ={object.id}>
          <div style={styles.wrapper}>
            <Link to={{ pathname: `${category}/${object.id}`, state: { id: object.id }}}>
            <img src={object.img} style={styles.image} />
            <div style={styles.description}>
              <div style={styles.descriptionContent}>{object.name}</div>
            </div>
            </Link>
          </div>
        </Col>
      )
    })}
    </Row>
  )
}

export default ProductsIteration;

我的迭代组件中的链接在我的导航栏中呈现“/:category/:id”url,但页面什么也不做。这是我使用路由器的第一个项目,任何指导将不胜感激。

【问题讨论】:

    标签: reactjs react-router react-router-v4 react-router-dom


    【解决方案1】:

    在 React 路由器 v4 中:

    • 路由器组件是从'react-router-dom'而不是'react-router'导入的。

    • 传统的&lt;Router/&gt; 组件已被&lt;BrowserRouter/&gt; 组件取代,不需要任何道具。

    • 嵌套路由不再是惯例。相反,您必须将 &lt;ProductShow/&gt; 作为 &lt;Route/&gt; 组件的 component 属性嵌套在 &lt;Switch/&gt; 组件内的 &lt;ProductIndexPage/&gt; 组件内。

    请参阅下面的示例。

    Router.js:

    // React.
    import React from 'react'
    
    // React Router DOM.
    import {
      BrowserRouter as Router,
      Route,
      Switch
    } from 'react-router-dom'
    
    // Routes.
    import App from './App'
    import CategoriesIndexPage from './pages/categories/CategoriesIndexPage'
    import ProductsIndexPage from './pages/products/ProductsIndexPage'
    import LocationsPage from './pages/LocationsPage'
    
    // Router.
    const Router = (
      <Router>
        <Switch>
          <Route exact path='/' component={App}/>
          <Route path='/categories' component={CategoriesIndexPage}/>
          <Route path='/locations' component={LocationsPage}/>
          <Route path='/:category/:id?' component={ProductsIndexPage}/>
        </Switch>
      </Router>
    )
    
    // Export.
    export default Router
    

    ProductIndexPage.js:

    // React.
    import React from 'react'
    
    // BW React Data.
    import {
      BWReactData
    } from '../../config/FirebaseConstants.js'
    
    // Head.
    import Head from '../../components/Head.js'
    
    // Foot.
    import Foot from '../../components/Foot.js'
    
    // Products Iteration.
    import ProductsIteration from './ProductsIteration'
    
    // Product Show.
    import ProductShow from './ProductShow'
    
    // React Router DOM.
    import {
      Switch
    } from 'react-router-dom'
    
    // Products Index Page.
    class ProductsIndexPage extends React.Component {
    
      // Constructor.
      constructor(props){
    
        // Super Props.
        super(props)
    
        // State.
        this.state = {
          allProducts: [],
          loading: true,
        }
      }
    
      // Did Mount.
      componentDidMount() {
        ...
      }
    
      // Render.
      render() {
        let allProducts = this.state.allProducts
        let loading = this.state.loading
        let categoryURL = this.props.location.state.category
    
        return (
          <div>
          <Head/>
          <ProductsIteration
            allProducts={allProducts}
            loading={loading}
            categoryURL={categoryURL}
          />
          {this.props.match.params.id ? (<ProductShow/>) : ''}
          <Foot/>
          </div>
        )
      }
    }
    

    【讨论】:

    • 感谢您,但在构建时会导致 ProductIndexPage 和 ProductShow 组件同时呈现在页面上,一个在另一个下方
    • 好的,当然。我已将代码修改为仅在存在 id 参数时显示 &lt;ProductShow/&gt; 组件。但我觉得你可能只想展示其中一个。如果是这种情况:在 &lt;ProductIndexPage/&gt; &lt;Route/&gt; 组件中放置一个 exact 属性,并在其下方使用 path="/:category/:id" specially for your ` 组件创建另一个 &lt;Route/&gt; 组件。父组件 &lt;Switch/&gt; 将处理其余部分。
    • React Router V4 可以使用&lt;Router&gt;。它用于自定义历史记录。见reacttraining.com/react-router/web/api/Router
    • 海报目前正在使用自定义历史对象,所以我认为他/她应该保留&lt;Router&gt;并使用history.push()等导航。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-04
    • 1970-01-01
    • 2019-05-30
    • 2017-02-03
    • 2017-08-28
    • 2015-02-21
    相关资源
    最近更新 更多