简体   繁体   中英

Passing props to a component using a variable (not a static component) in React router 5

I know that in react-router 5 you can pass some props to a child component like this:

<Route path="/"    
   exact
   render={ props => <MyPage title={myTitle} dataPath={myDataPath} 
   {...props} />} />

But in my case, I'm using a route model:

import { ComponentType, FC } from "react";

interface RouteItem {
  key: string;
  title: string;
  tooltip?: string;
  path?: string;
  component?: FC<{}>;
  contentPath?: string;
  enabled: boolean;
  icon?: ComponentType;
  subRoutes?: Array<RouteItem>;
  appendDivider?: boolean;
}

export default RouteItem;

I then define these in a config file ( config/index.ts ) like so:

// components
import DetailPageTemplate from "../pages/DetailPageTemplate";

// interface
import RouteItem from '../model/RouteItem.model';

// define app routes
export const routes: Array<RouteItem> = [
  {
    key: "router-detail-one",
    title: "Detail One",
    path: "/detail-one",
    enabled: true,
    contentPath: '../data/DetailOneCopy.json',
    component: DetailPageTemplate,
    appendDivider: true,
  },
  {
    key: "router-detail-two",
    title: "Detail Two",
    path: "/detail-two",
    enabled: true,
    contentPath: '../data/DetailTwoCopy.json',
    component: DetailPageTemplate,
    appendDivider: true,
  },
];

This feels like a very silly problem (my unfamiliarity with the syntax) but I want to be able to pass some of these parameters in a loop inside my App.tsx, and I can't figure out how to pass props to the component variable (since it's not JSX):

import React from 'react';

// components
import Layout from './components/global/Layout';
import { BrowserRouter as Router, Switch, Route } from 'react-router-dom';

// app routes
import { routes } from './config';

// interfaces
import RouteItem from './model/RouteItem.model';

// define app context
const AppContext = React.createContext(null);

// default component
const DefaultComponent = () => <div>No Component Defined.</div>;

function App() {
  // const [useDefaultTheme, toggle] = useReduc

  return (
    <>
      <AppContext.Provider value={null}>
          <Router>
            <Switch>
              <Layout>
                {routes.map((route: RouteItem) =>
                  (
                    <Route
                      key={`${route.key}`}
                      path={`${route.path}`}
                      component={route.component || DefaultComponent}
                      { /*       ^ How can I pass props to the component? */ }
                      exact
                    />
                  )
                )}
              </Layout>
            </Switch>
          </Router>
        </ThemeProvider>
      </AppContext.Provider>
    </>
  );
}

export default App;

I think you can use the route.component as JSX <route.component /> but for naming consistency (capitalization) you could assign it to a const first

              {routes.map((route: RouteItem) => {
                const Component = route.component;
                return (
                  <Route
                    key={`${route.key}`}
                    path={`${route.path}`}
                    component={
                      (Component &&
                        ((props: any) => <Component {...props} />)) ||
                      DefaultComponent
                    }
                    exact
                  />
                );
              })}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM