React入門 9:React Router

1. 什么是路由

路由routing)就是通過互聯(lián)的網(wǎng)絡(luò)信息從源地址傳輸?shù)侥康牡刂返幕顒?dòng)。

以上是中文維基百科對(duì)路由的解釋。通俗的來講,把一個(gè)地方的信息傳輸?shù)剿肴サ哪康牡氐倪^程,就叫路由。

2. 用代碼解釋路由

需求:頁(yè)面上有2個(gè)按鈕,分別是登陸和注冊(cè),點(diǎn)擊登陸按鈕,就切換到對(duì)應(yīng)的登陸界面,點(diǎn)擊注冊(cè)按鈕,就切換到對(duì)應(yīng)的注冊(cè)界面。

示例代碼:

function Box1(){
  return <div className="box">登陸</div>
}

function Box2(){
  return <div className="box">注冊(cè)</div>
}

function App() {
  let [n, setN] = useState(0)
  return (
    <div className="App">
      <div>
        <button onClick={()=> setN(0)}>登陸</button>
        <button onClick={()=> setN(1)}>注冊(cè)</button>
      </div>
      <div>
        { n % 2 === 0 ? <Box1 />:<Box2 />}
      </div>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

這個(gè)其實(shí)就是路由的雛形了,每個(gè)頁(yè)面對(duì)應(yīng)著一個(gè)組件,然后在不同狀態(tài)下去切換 。

3. 新增的需求

提出需求:在分享該頁(yè)面出去時(shí),用戶直接到達(dá)注冊(cè)頁(yè)面。(以上示例代碼的首頁(yè)是登陸界面)

3.1 修改 url 中的 hash

url 中 #(hash) 的含義
URL 的 hash 部分,指的是 # 后的部分
window.location.hash 可讀取或?qū)懭?hash

function Box1() {
  return <div className="box">登錄</div>;
}

function Box2() {
  return <div className="box">注冊(cè)</div>;
}

function App() {
  //獲取當(dāng)前的hash值
  let hash = window.location.hash;
  let initUI = hash === "#signup" ? "注冊(cè)" : "登錄";

  let [ui, setUI] = useState(initUI);

  //切換頁(yè)面時(shí),改hash
  let onClickLogin = () => {
    setUI("登錄");
    window.location.hash = "login";
  };

  let onClickSignUp = () => {
    setUI("注冊(cè)");
    window.location.hash = "signup";
  };

  return (
    <div className="App">
      <div>
        <button onClick={onClickLogin}>登錄</button>
        <button onClick={onClickSignUp}>注冊(cè)</button>
      </div>
      <div>{ui === "登錄" ? <Box1 /> : <Box2 />}</div>
    </div>
  );
}

#signup : 注冊(cè), 空或 #login: 登錄。
不同的界面對(duì)應(yīng)不同的字符串(hash),把用戶送往其想到達(dá)的目的地,就是路由。

3.2 除了 hash 還能用什么

但是,地址欄上有這個(gè) “#” 符號(hào)不太好看,能不能變好看點(diǎn)?

  • 直接修改 pathname ,但會(huì)刷新頁(yè)面
不用
window.location.hash = "login";
而用
window.location.pathname = "/login";

我只是想切換個(gè)tab,頁(yè)面就整個(gè)刷新了啊

  • 使用 window.history.pushState()
    可以不刷新頁(yè)面而改變 pathname。
window.history.pushState(null, '', '/login')
function App() {
  let path = window.location.pathname;
  let initUI = path === "/signup" ? "注冊(cè)" : "登錄";

  console.log(initUI);
  let [ui, setUI] = useState(initUI);

  let onClickLogin = () => {
    setUI("登錄");
    window.history.pushState(null, "", "/login");
  };

  let onClickSignUp = () => {
    setUI("注冊(cè)");
    window.history.pushState(null, "", "/signup");
  };

  return (
    <div className="App">
      <div>
        <button onClick={onClickLogin}>登錄</button>
        <button onClick={onClickSignUp}>注冊(cè)</button>
      </div>
      <div>{ui === "登錄" ? <Box1 /> : <Box2 />}</div>
    </div>
  );
}

3.3 三種方式的區(qū)別

  • window.location.hash (保險(xiǎn)辦法)
    可讓 url 變化,同時(shí)不刷新頁(yè)面
  • window.location.pathname
    會(huì)刷新頁(yè)面,別用
  • window.history.pushState( , , ) (想好看用這個(gè))
    不刷新頁(yè)面,并改變 pathname
    建議:只有后端將所有路徑都指向首頁(yè)時(shí),才使用這個(gè)API。

4. React Router

上面的代碼存在著重大缺陷:

  • 如果 path 過多,代碼就要寫很多 if ... else
  • 路由有無限個(gè),無法寫

暫不考慮使用正則表達(dá)式。使用 React Router 來解決這些問題吧 : )
React Router,保持 UI 和 URL同步。

4.1 安裝 React Router

使用命令行:

npm install react-router-dom

注意:
react-router: 實(shí)現(xiàn)了路由的核心功能。
react-router-dom: 基于react-router,加入了在瀏覽器運(yùn)行環(huán)境下的一些功能。
寫網(wǎng)站的時(shí)候一般引入 react-router-dom 就可以了

4.2 使用 React Router

建議查看的官網(wǎng):react-router

import { BrowserRouter as Router, Switch, Link, Route } from "react-router-dom";

function Home(){
  return <div className="box">首頁(yè)</div>
}
function Login(){
  return <div className="box">登錄</div>
}
function SignUp(){
  return <div className="box">注冊(cè)</div>
}

function App(){
  return(
    <div className="app">
      <Router>
        <div className="nav">
          <Link to="/" className="link">首頁(yè)</Link> | <Link to="/login" className="link">登錄</Link> | <Link to="/signup" className="link">注冊(cè)</Link>
        </div>
        <Switch>
          <Route exact path="/"> 
            <Home />
          </Route>
          <Route path="/login">
            <Login />
          </Route>
          <Route path="/signup">
            <SignUp />
          </Route>
        </Switch>
      </Router>
    </div>
  )
}

ReactDOM.render(<App />, document.getElementById('root'));

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容