使用 React 路由器更轻松地通过侧边栏导航动态呈现组件

Posted

技术标签:

【中文标题】使用 React 路由器更轻松地通过侧边栏导航动态呈现组件【英文标题】:Easier way to dynamically render components with sidebar navigation using react router 【发布时间】:2019-08-18 10:55:51 【问题描述】:

目前正在阅读本教程,使用 react router https://reacttraining.com/react-router/web/example/sidebar 创建侧边栏导航系统

我计划有多条路线,这意味着我必须继续导入路线并将它们添加到routes 数组中。是否有一种智能/正确的方法来动态加载它们?

我所有的组件都将在我的/Views 文件夹中。

App.js

import React,  Component  from 'react';
import SideBar from './components/SideBar/SideBar';
import MainContent from './components/MainContent/MainContent';
import  BrowserRouter as Router,
 from 'react-router-dom';


// Import all components here
import Button from './components/Views/Button/Button';
import Color from './components/Views/Color/Color';
import Card from './components/Views/Card/Card';
import Filter from './components/Views/Filter/Filter';

const routes = [
  
    path: "/",
    name: 'home',
    exact: true,
    main: () => <h2>Home</h2>
  ,
  
    path: "/button",
    name: 'Button',
    main: () =>  <Button />
  ,
  
    path: "/color",
    name: 'Color',
    main: () =>  <Color />
  ,
  
    path: "/card",
    name: 'Card',
    main: () =>  <Card />
  ,
  
    path: "/filter",
    name: 'Filter',
    main: () =>  <Filter />
  ,
];

class App extends Component 
  render() 
    return (
      <Router>
        <div className="ds-container">
          <SideBar routes=routes />
          <MainContent routes=routes />
        </div>
      </Router>
    );
  


export default App;

【问题讨论】:

你是用webpack打包的吗? 我只是使用create-react-app 给我的任何东西。 【参考方案1】:

由于您使用的是在内部使用 webpack 的 create-react-app,因此您可以查看 require-context。这将帮助您动态导入与某个正则表达式匹配的文件夹中的所有文件。 (例如:以 .jsx/.js 结尾)

但是,我建议您不要这样做:

    您永远不会知道您目前正在迎合哪些路线。 这可能会降低代码的可读性。 您可能还需要导出组件的映射(路由中的path)以及组件本身。

为避免所有这些,您可以简单地在 Views 组件中创建一个 index.js 文件,该文件需要您创建的任何新路由组件,并返回您在 App.js 文件中形成的最终数组。

基本上,/Views/index.js

// Import all components here
import Button from './components/Views/Button/Button';
import Color from './components/Views/Color/Color';
import Card from './components/Views/Card/Card';
import Filter from './components/Views/Filter/Filter';

const routes = [
  
    path: "/",
    name: 'home',
    exact: true,
    main: () => <h2>Home</h2>
  ,
  
    path: "/button",
    name: 'Button',
    main: () =>  <Button />
  ,
  
    path: "/color",
    name: 'Color',
    main: () =>  <Color />
  ,
  
    path: "/card",
    name: 'Card',
    main: () =>  <Card />
  ,
  
    path: "/filter",
    name: 'Filter',
    main: () =>  <Filter />
  ,
  // add new routes here
];

export default routes;

SideBar.js 中:

import routes from 'path/to/views/Views';

//rest of your code to render the routes.

这样,您可以清理 App.js 中的代码,还可以有效地分离各个组件的关注点。

我希望这是有道理的:)

【讨论】:

【参考方案2】:

有几种方法可以根据当前位置选择主要组件。但是所有这些都需要列出所有可能的路线并导入相应的组件。您可以使用dynamic imports 和React.lazy 来简化代码拆分。

但您可以避免对侧边栏进行额外配置。侧边栏可以从全局状态获取配置,您的主要组件可以在挂载时更新该状态(componentDidMountuseEffect(() =&gt; ..., [])):

const SideBarContext = React.createContext(() => );

function useSidebar(name) 
  const setSidebarName = useContext(SideBarContext);
  useEffect(() => 
    setSidebarName(name);
    return () => setSidebarName(null);
  , []);


function Home() 
  useSidebar('home');
  return <h2>Home</h2>;


function Button() 
  useSidebar('Button');
  return <button>press me</button>;


function App() 
  const [name, setName] = useState(null);

  return (
      <Router>
        <div className="ds-container">
          <SideBar name=name />
          <SideBarContext.Provider value=setName>
            <Route path="/" exact component=Home/>
            <Route path="/button" component=Button/>
          </SideBarContext.Provider>
        </div>
      </Router>
  );

所以每个组件都会关心侧边栏的选项,你只需要导入它们并添加Routes。

【讨论】:

以上是关于使用 React 路由器更轻松地通过侧边栏导航动态呈现组件的主要内容,如果未能解决你的问题,请参考以下文章

如何在 React 中登录页面后配置侧边栏导航中的路由?

React Router 4.0 ---- 嵌套路由和动态路由

Vue.js - 使用 vuex 打开/关闭动态侧边栏思想不同的组件(导航栏到侧边栏)

由于侧边栏和导航栏,React 中的未找到页面无法正常工作

vue 导航栏状态即时更新

如何使用反应原生导航 v2 添加侧边栏抽屉?