web-dev-qa-db-de.com

Mehrere Layouts mit React Router v4

Ich ziehe mir die Haare aus dem Kopf und versuche, mit React Router v4 mehrere Layouts zu rendern.

Ich möchte zum Beispiel, dass Seiten mit den folgenden Pfaden Layout 1 haben:

  • genauer Pfad = "/"
  • path = "/ blog"
  • path = "/ about"
  • path = "/ projects"

und die folgenden Pfade für Layout 2:

  • path = "/ blog /: id
  • path = "/ project /: id

Effektiv das, was hier außer für v4 beantwortet wird: Verwenden mehrerer Layouts für React-Router-Komponenten

7
redstripepapi

Keine der anderen Antworten hat funktioniert, daher habe ich die folgende Lösung gefunden. Ich habe die Stützerenderanstelle der traditionellen Stütze component auf der höchsten Ebene verwendet.

Es verwendet die Funktion layoutPicker, um das Layout basierend auf dem Pfad zu bestimmen. Wenn dieser Pfad keinem Layout zugewiesen ist, wird die Meldung "schlechte Route" zurückgegeben.

import SimpleLayout from './layouts/simple-layout';
import FullLayout from './layouts/full-layout';

var layoutAssignments = {
  '/': FullLayout,
  '/pricing': FullLayout,
  '/signup': SimpleLayout,
  '/login': SimpleLayout
}

var layoutPicker = function(props){
  var Layout = layoutAssignments[props.location.pathname];
  return Layout ? <Layout/> : <pre>bad route</pre>;
};

class Main extends React.Component {
  render(){
    return (
      <Router>
        <Route path="*" render={layoutPicker}/>
      </Router>
    );
  }
}


simple-layout.js und full-layout.js folgen diesem Format:

class SimpleLayout extends React.Component {
  render(){
    return (
      <div>
        <Route path="/signup" component={SignupPage}/>
        <Route path="/login" component={LoginPage}/>
      </div>
    );
  }
}
9
spencer.sm

Verwenden Sie hierfür die Renderfunktion ( https://reacttraining.com/react-router/core/api/Route/render-func ).

Ein wirklich guter Artikel, der mir geholfen hat: https://simonsmith.io/reusing-layouts-in-react-router-4/

Am Ende werden Sie so etwas verwenden:

<Router>
 <div>
  <DefaultLayout path="/" component={SomeComponent} />
  <PostLayout path="/posts/:post" component={PostComponent} />
 </div>
</Router>
5
Nikolay Novikov

Ich habe dieses Problem mit ein wenig Ihrer beiden Lösungen gelöst:

Meine Routes.js-Datei

import BaseWithNav from './layouts/base_with_nav';
import BaseNoNav from './layouts/base_no_nav';

function renderWithLayout(Component, Layout) {
  return <Layout><Component /></Layout>
}

export default () => (
  <Switch>
    {/* Routes with Sidebar Navigation */}
    <Route exact path="/" render={() => renderWithLayout(Home, BaseWithNav)} />

    {/* Routes without Sidebar Navigation */}
    <Route path="/error" render={() => renderWithLayout(AppErrorMsg, BaseNoNav)} />
    <Route path="/*" render={() => renderWithLayout(PageNotFound, BaseNoNav)} />
  </Switch>
)

Base.js (wo Routen importiert werden)

export default class Base extends React.Component {
  render()  {
    return (
      <Provider store={store}>
        <Router>
          <Routes />
        </Router>
      </Provider>
    )
  }
}

Layouts

BaseWithNav.js

class BaseWithNav extends Component {
  constructor(props) {
    super(props);
  }

  render() {        
    return <div id="base-no-nav">
      <MainNavigation />
      <main>
        {this.props.children}
      </main>
    </div>
  }
}

export default BaseWithNav;

BaseNoNav.js

class BaseNoNav extends Component {
  constructor(props) {
    super(props);
  }

  render() {
    let {classes} = this.props;

    return <div id="base-no-nav">
      <main>
        {this.props.children}
      </main>
    </div>
  }
}

export default BaseNoNav;

Ich hoffe das hilft!

0
Sixers17