1

react-router 的工作方式

是在组件树顶层放一个 Router 组件,然后在组件树中散落着很多 Route 组件(注意比 Router 少一个“r”),顶层的 Router 组件负责分析监听 URL 的变化,在它保护伞之下的 Route 组件可以直接读取这些信息。Router 是“提供者”,Route是“消费者”。如下:
// index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { HashRouter } from 'react-router-dom';
import './index.css';
import App from './App';

ReactDOM.render((
    <HashRouter><App /></HashRouter>
), document.getElementById('root'));
// App.js
import React, { Component } from 'react';
import Overview from './page/Home';
import GitHubStars from './page/GitHubInfo';

const { Content } = Layout;

class App extends Component {
    constructor(props) {
        super(props);
        this.state = {}
    }

    render() {
        return (
            <div>
                <Content>
                    <Switch>
                        <Route exact path="/" component={ Overview }/>
                        <Route exact path="/stars-info" component={ GitHubStars }/>
                    </Switch>
                </Content>
            </div>
        );
    }
}

export default App;
更进一步,Router 其实也是一层抽象,让下面的 Route 无需各种不同 URL 设计的细节。 URL设计方法,至少可以分为两种:

BrowserRouter

这一种很自然,比如 / 对应 Home页/about 对应 About 页,但是这样的设计需要服务器端渲染,因为用户可能直接访问任何一个 URL,服务器端必须能对 /的访问返回 HTML,也要对 /about的访问返回 HTML。BrowserRouter支持这种URL。

HashRouter

这一种看起来不自然,但是实现更简单。只有一个路径 /,通过 URL 后面的 # 部分来决定路由,/#/ 对应 Home 页,/#/about 对应 About 页。因为URL中#之后的部分是不会发送给服务器的,所以,无论哪个 URL,最后都是访问服务器的 / 路径,服务器也只需要返回同样一份 HTML就可以,然后由浏览器端解析 # 后的部分,完成浏览器端渲染。HashRouter支持这种URL。

注意:exact属性和Switch组件的作用

Route 组件的 path 属性用于匹配路径,因为我们需要匹配 / 到 Home,匹配 /about 到 About,所以肯定需要两个 Route,但是,我们不能这么写。
  <Route path='/' component={Home}/>
  <Route path='/about' component={About}/>
如果按照上面这么写,当访问 /about 页面时,不光匹配 /about,也配中 /,界面上会把 Home 和 About 都渲染出来的。
解决方法,可以在想要精确匹配的 Route 上加一个属性 exact,或者使用 Switch 组件(可以把 Switch 组件看做是 JavaScript 的 switch 语句,从上往下找第一个匹配的 Route,匹配中了之后,立刻就 break,不继续这个 Switch 下其他的 Route 匹配了):
<Switch>
    <Route exact path='/' component={Home}/>
    <Route path='/about' component={About}/>
</Switch>

如何选择

因为 create-react-app 产生的应用默认不支持服务器端渲染,为了简单起见,我们在下面的例子中使用 HashRouter,在实际产品中,其实最好还是用 BrowserRouter,这样用户体验更好。

星不克
52 声望2 粉丝

一蓑烟雨任平生