React-Router在單頁應用中的簡單介紹

在React中使用React Router來構建單頁應用

1、爲何須要路由

在咱們使用React來構建單頁App的時候,最大的區別是,導航一個頁面應用程序並不涉及到一個全新的頁面。而是你的整個應用是在同一個頁面進行操做的。

當你加載網頁內容的時候,將會變得有一點困難,困難的部分不是加載內容自己,這相對來講比較容易,而是確保單頁應用的行爲與用戶習慣性的操做行爲保存一致,更顯著的是,當用戶導航使用你的App時候,有如下幾點問題:html

  1. 在地址欄顯示的URL總可以反映出視圖展現的東西
  2. 可以成功地使用瀏覽器的返回和前進按鈕
  3. 可以直接的使用相關聯的URL導航到某個特別的視圖
對於多頁應用,這三點是不用去考慮的,也沒有額外的你不得不去爲多頁應用考慮的。而對於單頁應用,由於你不能導航到一個完成新的頁面,你不得不真正的去處理這三個你的用戶指出的問題。你須要確保導航進入你的App的URL是徹底正確的。你須要確保瀏覽器的歷史記錄每一個導航都是同步的來准許用戶使用後退或前進按鈕。若是用戶標記(收藏)了某個特殊的視圖或複製粘貼了一URL以便以後能夠訪問,你須要確保的是你的單頁應用可以將用戶引導正確的位置。

爲了處理以上的問題,你須要有一門一般叫作路由的技術。react

2、開始

二.一 構建App

create-react-app react_spa
cd react_spa
npm i react-router-dom --save

2、二 整理項目結構

將原來項目中publicsrc文件夾下的全部文件(夾)刪除,而後在public文件夾下建立一個index.html將服務於咱們App的開始入口。git

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport"
          content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta name="theme-color" content="#000000">
    <title>React Router Example</title>
  </head>
  <body>
    <div id="root"></div>
  </body>
</html>

以後在src文件夾下建立一個index.js文件做爲咱們的入口文件,並添加下面內容:github

import React from "react";
import ReactDOM from "react-dom";
import Main from "./Main";
 
ReactDOM.render(
  <Main/>, 
  document.getElementById("root")
);

接下來在src文件夾下面建立一個Main.js文件做爲路由的配置文件:npm

import React, { Component } from "react";
 
class Main extends Component {
  render() {
    return (
        <div>
          <h1>Simple SPA</h1>
          <ul className="header">
            <li><a href="/">Home</a></li>
            <li><a href="/stuff">Stuff</a></li>
            <li><a href="/contact">Contact</a></li>
          </ul>
          <div className="content">
             
          </div>
        </div>
    );
  }
}
 
export default Main;

構建內容頁面:api

Home.js瀏覽器

import React, { Component } from "react";
 
class Home extends React.Component {
  render() {
    return (
      <div>
        <h2>HELLO</h2>
        <p>Cras facilisis urna ornare ex volutpat, et
        convallis erat elementum. Ut aliquam, ipsum vitae
        gravida suscipit, metus dui bibendum est, eget rhoncus nibh
        metus nec massa. Maecenas hendrerit laoreet augue
        nec molestie. Cum sociis natoque penatibus et magnis
        dis parturient montes, nascetur ridiculus mus.</p>
 
        <p>Duis a turpis sed lacus dapibus elementum sed eu lectus.</p>
      </div>
    );
  }
}
 
export default Home

Stuff.jsreact-router

import React, { Component } from "react";
 
class Stuff extends React.Component {
  render() {
    return (
      <div>
        <h2>STUFF</h2>
        <p>Mauris sem velit, vehicula eget sodales vitae,
        rhoncus eget sapien:</p>
        <ol>
          <li>Nulla pulvinar diam</li>
          <li>Facilisis bibendum</li>
          <li>Vestibulum vulputate</li>
          <li>Eget erat</li>
          <li>Id porttitor</li>
        </ol>
      </div>
    );
  }
}
 
export default Stuff

Contact.jsapp

import React, { Component } from "react";
 
class Contact extends React.Component {
  render() {
    return (
      <div>
        <h2>GOT QUESTIONS?</h2>
        <p>The easiest thing to do is post on
        our <a href="https://github.com/huangche007">GitHub</a>.
        </p>
      </div>
    );
  }
}
 
export default Contact

3、使用路由

Main組件中已經有了這個App的基本框架,也有了HomeStuffContact三個內容組件了,如今須要作的就是將它們鏈接起來構建成咱們的App,這時候就須要使用到了React 路由了,回到Main.js,確保導入的語句以下:框架

import React, { Component } from "react";
import {
  Route,
  NavLink,
  HashRouter
} from "react-router-dom";
import Home from "./Home";
import Stuff from "./Stuff";
import Contact from "./Contact";

React路由工做方式被定義成一種稱爲路由區域,在路由區域裏,有兩件事可作:

  1. 導航的鏈接
  2. 將頁面內容加載到容器裏

導航的鏈接:在Main.js組件的render方法中增長<HashRouter>的代碼:

class Main extends Component {
  render() {
    return (
     <HashRouter>
        <div>
          <h1>Simple SPA</h1>
          <ul className="header">
            <li><a href="/">Home</a></li>
            <li><a href="/stuff">Stuff</a></li>
            <li><a href="/contact">Contact</a></li>
          </ul>
          <div className="content">
             
          </div>
        </div>
      </HashRouter>
    );
  }
}

HashRouter組件爲導航和由路由組成的瀏覽器歷史記錄操做提供了基礎,接下來將定義導航的鏈接,使用特殊的NavLink組件替換掉a標籤,併爲這樣的組件添加to屬性.

class Main extends Component {
  render() {
    return (
      <HashRouter>
        <div>
          <h1>Simple SPA</h1>
          <ul className="header">
            <li><NavLink to="/">Home</NavLink></li>
            <li><NavLink to="/stuff">Stuff</NavLink></li>
            <li><NavLink to="/contact">Contact</NavLink></li>
          </ul>
          <div className="content">
             
          </div>
        </div>
      </HashRouter>
    );
  }
}

注意每一個鏈接,將讓路由得知導航到的URL,URL的值(經過to屬性定義)做爲一個標識來確保正確的內容獲得加載,咱們匹配內容的URL的方式在Route(路由)組件中獲得使用

class Main extends Component {
  render() {
    return (
      <HashRouter>
        <div>
          <h1>Simple SPA</h1>
          <ul className="header">
            <li><NavLink to="/">Home</NavLink></li>
            <li><NavLink to="/stuff">Stuff</NavLink></li>
            <li><NavLink to="/contact">Contact</NavLink></li>
          </ul>
          <div className="content">
            <Route path="/" component={Home}/>
            <Route path="/stuff" component={Stuff}/>
            <Route path="/contact" component={Contact}/>
          </div>
        </div>
      </HashRouter>
    );
  }
}

正如你所見到的,Route組件包含一個path屬性,指定的path值決定了路由什麼時候被激活。當路由激活的時候,經過組件prop指定的組件將被渲染。好比:當點擊Stuff連接的時候,path值爲/stuff的路由變成了激活狀態,也就意味着Stuff組件的內容獲得了渲染。

接下來能夠npm start 來看看效果了。

4、修復路由

當運行起來以後,會發現,不管咱們切換的Stuff,Contact,Home組件的內容一直存在,這意味着不管導航到哪一個路由,Home組件老是可以匹配上,這是不對的。能夠在Home路由組件中,增長exact屬性來解決。

<div className="content">
  <Route exact path="/" component={Home}/>
  <Route path="/stuff" component={Stuff}/>
  <Route path="/contact" component={Contact}/>
</div>

exact屬性可以確保只有路由路徑正確的匹配,那麼這個路由組件才能將加載

5、效果圖

圖片描述

相關文章
相關標籤/搜索