使用 react-router 嵌套相对路由

Nesting relative routes with react-router

我有一个类别索引页面,它 link 指向特定于该类别的产品的产品索引页面。这么多功能。但是,当我尝试单击产品 linked 到特定于该产品的显示组件时,我遇到了麻烦。下面是我的代码:

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;

我的迭代组件中的 link 在我的导航栏中呈现 '/:category/:id' url 但该页面不执行任何操作。这是我使用路由器的第一个项目,任何指导将不胜感激。

在 React Router v4 中:

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

  • 传统的 <Router/> 组件已替换为 <BrowserRouter/> 组件,不需要道具。

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

示例见下方。

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