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
posted @ 2021-06-25 15:01  行露  阅读(890)  评论(0编辑  收藏  举报
the end