简体   繁体   English

React Router v4多个动态路由

[英]React Router v4 Multiple Dynamic Routes

I'm new to React Router so if this has been asked before maybe someone could point me in the right direction! 我是React Router的新手,所以如果有人问过这个问题,也许有人可以向我指出正确的方向! Basically I have a WordPress install that I'm pulling in my websites data from through the API. 基本上,我安装了WordPress,并通过API从我的网站中提取数据。

I've created custom routes to query my pages and my posts by slug. 我已经创建了自定义路由来通过slug查询我的页面和帖子。

Using react router I was able to create a template called Page.js which changes dynamically using the code below. 使用React Router,我能够创建一个名为Page.js的模板,该模板使用以下代码动态更改。

However, now I'm trying to do the same exact thing with the blog posts but the app isn't using Blog.js its still defaulting back to Page.js 但是,现在我正在尝试对博客帖子执行相同的操作,但是该应用程序未使用Blog.js,它仍默认返回到Page.js

here's my App.js code... 这是我的App.js代码...

import React from "react";
import { BrowserRouter as Router, Route } from "react-router-dom";
import Home from './pages/Home';
import Page from './pages/Page';
import Blog from './pages/Blog';
import Header from './components/Header';
import Footer from './components/Footer';

class App extends React.Component {
  render() {
    return (
      <Router>
      <div>
          <Header/>
          <Route exact path="/" component={Home} />
          <Route path="/:slug" component={Page} />
          <Route path="/blog/:slug" component={Blog} />
          <Footer/>
      </div>
      </Router>
    );
  }
}

export default App;

More Details: 更多细节:

Page.js works by checking const { slug } = this.props.match.params; Page.js通过检查const {slug} = this.props.match.params;来工作。 and then querying WordPress using that slug to pull in the data it needs. 然后使用该标签查询WordPress,以提取所需的数据。 In componentDidUpdate i'm checking prevProps to see if the slug matches the previous slug, if not it fetching the new data. 在componentDidUpdate中,我正在检查prevProps以查看该段是否与先前的段匹配,如果不匹配则读取新数据。

This works great and I was hoping to do the same in the Blog.js as well. 这很好用,我也希望在Blog.js中也做同样的事情。

However, if this isn't the best approach please advise another method. 但是,如果这不是最佳方法,请建议另一种方法。

Two things: 两件事情:

  1. Use element : This will allow only one route to be used, no composing. 使用元素 :这将只允许使用一条路线,而无需编写路线。 ( See this documentation ) 请参阅本文档
  2. Check the order of path statements : Use defined paths before :param, this avoids considering /blog/:slug as a /:slug parameter. 检查路径语句的顺序 :在:param之前使用定义的路径,这样可以避免将/ blog /:slug视为/:slug参数。

` `

import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
class App extends React.Component {
  render() {
    return (
      <Router>
      <div>
          <Header/>
          <Switch>
              <Route exact path="/" component={Home} />
              <Route path="/blog/:slug" component={Blog} />
              <Route path="/:slug" component={Page} />
          </Switch>
          <Footer/>
      </div>
      </Router>
    );
  }
}

I think you're pretty close to the recommended implementation, just a few small tweaks should get you there. 我认为您已经非常接近建议的实施方式,只需进行一些小调整就可以达到目标。

First, 第一,
In your App.js file you're actually handling routing, without using the <Switch> component provided by React Router, replacing the <div> and </div> tags in your App.js file with <Switch> and </Switch> respectively should get this working for you. 在您的App.js文件中,您实际上是在处理路由,而不使用React Router提供的<Switch>组件, App.js<Switch></Switch> App.js文件中的<div></div>标签</Switch>分别应该为您工作。 See below... 见下文...

import React from "react";
import { BrowserRouter as Router, Route, Switch } from "react-router-dom"; //make sure you import it also!
import Home from './pages/Home';
import Page from './pages/Page';
import Blog from './pages/Blog';
import Header from './components/Header';
import Footer from './components/Footer';

class App extends React.Component {
  render() {
     return (
      <Router>
        <Switch> //Add this in
          <Header />
          <Route exact path="/" component={Home} />
          <Route path="/blog/:slug" component={Blog} />
          <Route path="/:slug" component={Page} />
          <Footer />
       </Switch> //Add this in
     </Router>
    );
  }
}

export default App;



I would recommend going further though! 我建议走得更远!

To make these components more understandable, you should refactor routing functionality into a routes.js file, and top-level App component logic/structure into the App.js file. 为了使这些组件更易于理解,您应该将路由功能重构为routes.js文件,并将顶级App组件逻辑/结构 App.jsApp.js文件。 See below... 见下文...


In App.js : App.js

This file is where you should handle your base application structure and logic. 该文件是您应处理基本应用程序结构和逻辑的地方。 For example this file is where you'll import your <Header> , your <Footer> , and where the Route component will render. 例如,此文件是您导入<Header><Footer>以及Route组件将在其中渲染的位置。

import * as React from 'react'
import Header from './../Header/Header.jsx'
import Footer from './../Footer/Footer.jsx'

class App extends React.Component {
    constructor(props) {
        super(props)
        this.state = {
         // Handle your top-level application state here
        }
    }

    // define your top-level application functions here

    render() {
        return (
            <div>
                <Header />
                <main>
                    {this.props.children} //This where the Route components will render
                </main>
                <Footer />
            </div>
        )
    }
}

export default App


In Routes.js : Routes.js

This file is where you should import your App component, and then handle the routing statements. 该文件是您应import App组件,然后处理路由语句的位置。

import React from 'react'
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom'

import App from './components/App'
import Home from './pages/Home'
import Page from './pages/Page'
import Blog from './pages/Blog'

/* construct routes */
export default () => {
    return (
        <Router>
            <App>
                <Switch>
                    <Route path='/' exact component={Home} />
                    <Route path='/blog/:slug' component={Blog} />
                    <Route path='/:slug' component={Page} />
                </Switch>
            </App>
        </Router>
    )
}

If you structure your application this way, your routing logic and top-level application logic are separate, and in the end your files will be less cluttered as both Route files and top-level App files can get fairly dense. 如果以这种方式构造应用程序,则路由逻辑和顶级应用程序逻辑是分开的,最终,由于Route文件和顶级App文件会变得相当密集,因此文件将变得更加混乱。

Hope this helps! 希望这可以帮助! Let me know if I can explain anything further. 让我知道是否可以进一步解释。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM