web-dev-qa-db-fra.com

Plusieurs mises en page avec React Router v4

Je tire mes cheveux en essayant de rendre plusieurs mises en page avec React Router v4.

Par exemple, j'aimerais que les pages avec les chemins suivants aient la mise en page 1:

  • chemin exact = "/"
  • path = "/ blog"
  • path = "/ about"
  • chemin = "/ projets"

et les chemins suivants pour avoir la disposition 2:

  • chemin = "/ blog /: id
  • chemin = "/ projet /: id

Ce qui est effectivement résolu ici, sauf pour la v4: Utilisation de plusieurs dispositions pour les composants de réag-routeur

7
redstripepapi

Aucune des autres réponses n’ayant fonctionné, j’ai donc proposé la solution suivante. J'ai utilisé lerenderprop au lieu du traditionnel component prop au plus haut niveau.

Il utilise la fonction layoutPicker pour déterminer la mise en page en fonction du chemin. Si ce chemin n'est pas affecté à une mise en page, il renvoie un message "itinéraire incorrect".

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 et full-layout.js suivent ce format:

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

Donc, pour cela, vous devez utiliser la fonction de rendu ( https://reacttraining.com/react-router/core/api/Route/render-func )

Un très bon article qui m'a aidé: https://simonsmith.io/reusing-layouts-in-react-router-4/

En fin de compte, vous utiliserez quelque chose comme ceci: 

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

J'ai résolu ce problème en utilisant un peu de vos deux solutions:

Mon fichier Routes.js

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 (où les itinéraires sont importés)

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;

J'espère que ça aide!

0
Sixers17