使用react-router嵌套相对路由

时间:2017-11-01 03:33:39

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

我有一个类别索引页面,该页面链接到特定于该类别的产品的产品索引页面。这很有用。但是,当我尝试点击链接到特定于该产品的节目组件的产品时,我遇到了麻烦。以下是我的代码:

router.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;

我的迭代组件中的链接呈现&#39; /:category /:id&#39;我的导航栏中的网址,但页面什么也没做。这是我的第一个使用路由器的项目,任何指导都将非常感谢。

1 个答案:

答案 0 :(得分:3)

在React Router v4中:

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

  • 传统的<Router/>组件已被<BrowserRouter/>组件取代,后者不需要道具。

  • 嵌套路线不再是惯例。相反,您必须将<ProductShow/>作为component组件的<Route/>道具嵌套在<Switch/>组件的<ProductIndexPage/>组件中。< / p>

请参阅下面的示例。

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