使用反应路由器通过侧边栏导航动态渲染组件的更简单方法

Easier way to dynamically render components with sidebar navigation using react router

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

我计划有多条路线,这意味着我必须继续导入路线并将它们添加到 routes 数组中。有没有 smart/right 动态加载它们的方法?

我的所有组件都将在我的 /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,您可以查看 require-context。这将帮助您动态导入文件夹中与特定正则表达式匹配的所有文件。 (例如:以 .jsx/.js 结尾)

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

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

为了避免这一切,您可以简单地在 Views 组件中创建一个 index.js 文件,该文件需要您创建的任何新路由组件和 return 最终数组你已经在 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 中的代码,并且还能够有效地分离各个组件的关注点。

我希望这是有道理的:)

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

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

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。