web-dev-qa-db-ja.com

Reactルーターv4の複数のレイアウト

React Routerv4で複数のレイアウトをレンダリングしようとしています。

たとえば、次のパスのページのレイアウトを1にします。

  • 正確なパス= "/"
  • path = "/ blog"
  • path = "/ about"
  • path = "/ projects"

レイアウト2を持つための次のパス:

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

事実上、ここで答えられているのはv4の場合です: react-routerコンポーネントに複数のレイアウトを使用

9
redstripepapi

他の答えはどれもうまくいかなかったので、私は次の解決策を思いつきました。最高レベルの従来のrender小道具の代わりにcomponent小道具を使用しました。

layoutPicker関数を使用して、パスに基づいてレイアウトを決定します。そのパスがレイアウトに割り当てられていない場合は、「不正なルート」メッセージが返されます。

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およびfull-layout.js次の形式に従います:

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

したがって、これにはレンダリング関数を使用する必要があります( https://reacttraining.com/react-router/core/api/Route/render-func

私を助けてくれた本当に良い記事: https://simonsmith.io/reusing-layouts-in-react-router-4/

最終的には、次のようなものを使用します。

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

私はあなたの両方の解決策のビットを利用してこの問題を解決しました:

My 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(ルートがインポートされる場所)

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

レイアウト

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;

これがお役に立てば幸いです。

1
Sixers17