React基於Router的導航欄顯示


技術概述

什么情況下會使用到這個技術?

React需要在主頁面基於Router獲取當前的路由,並變更是否顯示類似導航欄之類的組件。

學習該技術的原因

在利用React框架做頁面設計的時候,一般不是所有的頁面都需要導航欄,這種情況下就可以使用這種方式來進行判斷。

技術的難點在哪里?

React有類組件和函數組件模式,基於不同的組件,可以使用的方法不一樣。而且,有些方法容易出現bug。

技術詳述

流程圖

類組件

1. 在app.jsx中獲取到當前路由

const { pathname } = this.props.history.location

2. 通過對獲取到的路由進行判斷是否顯示導航欄

return (
  <div>
    <Switch>
      <RouteAuth />
    </Switch>
    {pathname.indexOf('main') === -1 ? '' : <MainTabBar pathname={pathname} />}
  </div>
)

3. 使this.props含有路由參數

// App.jsx
export default withRouter(App);
// index.js
<Router>
  <App />
</Router>

由於app.jsx這個頁面是由瀏覽器直接打開的,所以在使用this.props時,獲取到的數據是為空的。(詳細如下)

通過withRouter包裹后,類似於:

// 將組件包裹進 Route, 然后返回
 const withRouter = () => {
     return () => {
         return <Route component={App} />
     }
 }

之后通過this.props可以獲取到內容。並且,在使用了withRouter之后,需要把BrowserRouter放在index.js中,否則就會報錯。(詳細如下)

函數式組件

1. 將layout部分單獨抽離出來

P.S.:當然,不抽離出來也是OK的

2. 通過useLocation獲取到當前的路由,並用useEffect監聽

// index.jsx
import { Layout as ALayout } from "antd";
import { useEffect, useState } from "react";
import { useLocation } from "react-router-dom";
import Sidebar from "../sidebar/index";

const { Content, Sider } = ALayout;

const Layout = ({ children }) => {
  const { pathname } = useLocation();
  const [showSidebar, setShowSideBar] = useState(false);
  const [collapsed, setCollapsed] = useState(false);

  useEffect(() => {
    console.log(pathname);
    setShowSideBar(pathname.indexOf("login") === -1);
  }, [pathname]);

  const hanldeCollapse = (collapsed) => {
    setCollapsed(collapsed);
  };

  return (
    <ALayout className="alayout" style={{ minHeight: "100vh" }}>
      {showSidebar && (
        <Sider collapsible collapsed={collapsed} onCollapse={hanldeCollapse}>
          <Sidebar />
        </Sider>
      )}

      <Content>{children}</Content>
    </ALayout>
  );
};

export default Layout;

3. 在Layout組件中放入需要路由的組件

function App() {
  return (
    <div className="App">
      <Router basename={process.env.PUBLIC_URL}>
        <Layout>
          <Switch>
            <RouteAuth />
          </Switch>
        </Layout>
      </Router>
    </div>
  );
}

技術使用中遇到的問題和解決過程

  1. App.jsx中無法使用useLocation,會報錯無法找到location這個對象。至於解決方法,額,目前沒找到,只能放棄。
  2. 如果使用useHistory來獲取pathname的方式,只有在頁面刷新的時候,才會重新獲取pathname的值。額,目前也沒有找到方法解決。

總結

就我使用情況來說,覺得函數式的組件更優於類組件。使用函數式組件的話,還可以利用Antdlayout布局進行封裝。通過使用react-router-dom中的useLocation進行獲取路由,並使用useEffect來監聽其中的pathname是否發生改變,如果改變,則更新狀態。通過以上的方法,來達到函數式組件的變更是否顯示導航欄的效果。

參考

  1. 淺談react傳入路由參數---withRouter組件
  2. react withRouter


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM