Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Injecting routes programmatically into a JSX router switch statement

I've been trying to inject some JSX routes into a router switch statement without success. Basically I'm trying to be able to reuse the method commonRoutes for different scenarios so I do not have to repeat myself... However when I inject the routes as illustrated the routing does not behave as expected and multiple routes will trigger at the same time instead of conditionally... hopefully the code illustrates clearly what I'm trying to do:

First try:

class App extends Component {
  commonRoutes() {
    return (
      <Switch>
        <Route path="/route1" component={Component1} />,
        <Route path="/route2" component={Component2} />,
        <Route path="/route3" component={Component3} />,
      </Switch>
    );
  }

  app() {
    return (
      <React.Fragment>
        <Header />
        <div className="app-content">
          <Switch>
            <Redirect exact from="/" to="/folder" />,
            {this.commonRoutes()},
            <Route path="*" component={NotFound} />
          </Switch>
        </div>
        <Footer />
      </React.Fragment>
    );
  }

  render() {
    let content = '';

    if (this.props.component === ComponentList.COMPONENT_APP) {
      return this.appFrame(this.app());
    } 

    if(this.props.component === ComponentList.COMPONENT_FOLDER) {
      return this.appFrame(this.folder());
    } 

    if (this.props.component === ComponentList.COMPONENT_EVENT) {
      return this.appFrame(this.event());
    }

    return content;
  }

  appFrame(content) {
    return (
      <React.Fragment>
        <CssBaseline/>
        <NotSupported  support={[{ name: 'ie', minSupport: 11 }]}/>
        <Favicon url={`${AppConfig.CONTEXT}favicon.ico`}/>
        <MuiThemeProvider theme={theme}>
          {content}
        </MuiThemeProvider>
      </React.Fragment>
    );
  }
  //... code
}

Second try:

class App extends Component {
  commonRoutes() {
    return [
      <Route path="/route1" component={Component1} />,
      <Route path="/route2" component={Component2} />,
      <Route path="/route3" component={Component3} />
    ];
  }

  app() {
    return (
      <React.Fragment>
        <Header />
        <div className="app-content">
          <Switch>
            <Redirect exact from="/" to="/folder" />,
              {this.commonRoutes()},
            <Route path="*" component={NotFound} />
          </Switch>
        </div>
        <Footer />
      </React.Fragment>
    );
  }
}

Another way that comes to mind is using an object with keys to store the JSX routes and looping with map, but several attempts did not do the trick either.

I appreciate any help or direction.

like image 331
andriusain Avatar asked Mar 07 '26 02:03

andriusain


1 Answers

First thing,

let content = ''
if (...) {
  return this.appFrame(this.app());
} 
...
return content

The preceding code works but not the way you expect. You're trying to return the content after the condition is matched. This just return the this.appFrame(...).

let content = ''
if (...) {
  content = this.appFrame(this.app());
} 
...
return content

Now, this works the way you're expecting. It assigns the value to the content and finally return the content.

Now, to your issue, you should be using exact props to return only the required component:

commonRoutes() {
    return (
      [
        <Route exact path="/route1" component={Component1} />,
        <Route exact path="/route2" component={Component2} />,
        <Route exact path="/route3" component={Component3} />
      ]
    );
  }

Also, ensure to use unique key when you render array of elements. In your case, it is [<Route key={'unique-key'} />,...].

And also remove path from here:

<Route path="*" component={NotFound} />
{/* -----^^ not required react router 4 */}
like image 57
Bhojendra Rauniyar Avatar answered Mar 08 '26 15:03

Bhojendra Rauniyar



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!