使用React Router v4的嵌套路由 - 解决方案

时间:2017-03-29 15:15:12

标签: javascript reactjs react-router

我正在尝试在React Router v4上运行嵌套路由。我指的是此页https://reacttraining.com/react-router/web/guides/quick-start

那么他们如何做嵌套路线就是这个

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

const BasicExample = () => (
  <Router>
    <div>
      <ul>
        <li><Link to="/">Home</Link></li>
        <li><Link to="/about">About</Link></li>
        <li><Link to="/topics">Topics</Link></li>
          </ul>

      <hr/>

      <Route exact path="/" component={Home}/>
      <Route path="/about" component={About}/>
      <Route path="/topics" component={Topics}/>
    </div>
  </Router>
)

const Home = () => (
  <div>
    <h2>Home</h2>
  </div>
)

const About = () => (
  <div>
    <h2>About</h2>
  </div>
)

const Topics = ({ match }) => (
  <div>
    <h2>Topics</h2>
    <ul>
      <li>
        <Link to={`${match.url}/rendering`}>
          Rendering with React
        </Link>
      </li>
      <li>
        <Link to={`${match.url}/components`}>
          Components
        </Link>
      </li>
      <li>
        <Link to={`${match.url}/props-v-state`}>
          Props v. State
        </Link>
      </li>
    </ul>

    <Route path={`${match.url}/:topicId`} component={Topic}/>
    <Route exact path={match.url} render={() => (
      <h3>Please select a topic.</h3>
    )}/>
  </div>
)

const Topic = ({ match }) => (
  <div>
    <h3>{match.params.topicId}</h3>
  </div>
)

export default BasicExample

这很明显,但我想把它改成类格式。

所以我在下面尝试了

index.js

render((
        <Router>
            <div>
                <Route path="/" component={App}/>
            </div>
        </Router>
    ), document.getElementById('root')
);

App.js

class App extends Component {
    render() {
        return (
            <div className="container">
                <header>
                    <span className="icn-logo"><i className="material-icons">code</i></span>
                    <ul className="main-nav">
                        <li><Link to="/">Home</Link></li>
                        <li><Link to="/about">About</Link></li>
                        <li><Link to="/teachers">Teachers</Link></li>
                        <li><Link to="/courses">Courses</Link></li>
                    </ul>
                </header>
                <Route exact path="/" component={Home}/>
                <Route path="/about" component={About}/>
                <Route path="/teachers" component={Teachers}/>
                <Route path="/courses" component={Course}/>
            </div>
        );
    }
}

export default App;

问题在于,当我点击链接时,它会路由到正确的网址并且它可以正常工作但是当我自己键入网址时,即使它们都渲染到相同的网址,它也无法获取/关闭等等 - 我是否点击链接或我是否自己输入链接。我想App路由没有呈现,除了在root,我不明白为什么。有谁知道为什么会这样?

另外,如何转换代码以便我可以像第一个示例代码一样接受匹配参数?所以在主题中它将匹配对象作为参数,我猜这是对其先前URL的某种引用

好的,我将在这里提供解决方案,因为很多基于视频的React Router教程都没有涵盖React Router v4。我希望那些正在努力使用新React路由器的新手可以从这个答案中获得帮助。

所以基本上你必须能够区分客户端路线和资产请求,webpack-dev-server为此提供了一个完美的选择。

您只需添加

即可
devServer: {
    port: 3000,
    historyApiFallback: {
        index:'index.html'
    }
}

到webpack.config.js,当服务器没有响应时,它总是指向index.html

这是我的参考。阅读它https://jaketrent.com/post/pushstate-webpack-dev-server/

可能会有用

1 个答案:

答案 0 :(得分:3)

这通常是服务器问题,而不是客户端代码中的任何问题。如果您使用带静态服务的快递:

app.use(express.static('build'));

然后,如果目录build中没有文件,或者另一个匹配例如/about然后表达不会回应任何事情。

除了上面的静态中间件之外,你还需要添加一个catch来表达所有路由 - 它必须在你的路由定义之后。

app.get('*', (req, res) => {
    res.sendFile(path.join(__dirname, '../build', 'index.html'));
};

这是一个通配符路由,因此静态中间件未匹配的任何内容都将发送到index.html。一旦它落入你的浏览器,那么react-router将接管并加载正确的组件。