1

Related post on Github

Currently I have a hard time using the two libraries in my react-redux app correctly.

My codes look like:

index.js

import { Provider } from 'react-redux';
import { ConnectedRouter } from 'connected-react-router';
...
ReactDOM.render(
  <Provider store={store}>
    <ConnectedRouter history={history}>
      <App />
    </ConnectedRouter>
  </Provider>,
  rootElement
);

App.js

...
export default () => (
  <Layout>
    <Switch>
      <Route exact path="/" component={Home} />
      <Route path="/test" component={Test} />
    </Switch>
  </Layout>
);

Layout.js

...
export default function Layout(props) {
  return (
    <div class="ms-Fabric">
      <div class="ms-Grid-row">
        <div class="ms-Grid-col ms-lg2">
          <Navigation />
        </div>
        <div class="ms-Grid-col ms-lg10">{props.children}</div>
      </div>
    </div>
  );
}

Navigation.js

import React from 'react';
import { withRouter } from 'react-router-dom';
import { Nav } from 'office-ui-fabric-react';

export default withRouter(({ history }) => (
  <div className="ms-NavExample-LeftPane">
    <Nav
      onLinkClick={(event, element) => {
        event.preventDefault();
        history.push(element.url);
      }}
      groups={[
        {
          links: [
            {
              name: 'Home',
              url: '/',
              key: 'home'
            },
            {
              name: 'Test',
              url: '/Test',
              key: 'test'
            }
          ]
        }
      ]}
    />
  </div>
));

However, when I run the app it shows You should not use <Route> outside a <Router>. The navigation is certainly in the ConnectedRouter and it seems this router works well with react-router v4 so I'm not sure how to deal with this problem.

Could anyone please give me a suggestion?

kemakino
  • 1,041
  • 13
  • 33

1 Answers1

0

The architecture of your project: Provider > ConnectedRouter > App > Layout (have NavLink) > Switch > Routes

You have to build architecture in this way: Provider > ConnectedRouter > routes file > Switch > Routes > Layout in component

// index.js
import React from 'react';
import { render } from 'react-dom';
import { Provider } from 'react-redux';
import { ConnectedRouter } from 'connected-react-router';
import routes from 'routes/index';
import store from 'store/configureStore';

render(
  <Provider store={store}>
    <ConnectedRouter history={history}>
      {routes}
    </ConnectedRouter>
  </Provider>,
  document.getElementById('root'),
);

// routes.js
const routes = (
  <Switch>
    <Route exact path="/" component={Home} />
    <Route path="/test" component={Test} />
  </Switch>
);

export default routes;
Vasyl Nahuliak
  • 1,912
  • 2
  • 14
  • 32
  • Thanks for your answer, but where in your example can I put the layout? – kemakino Nov 27 '18 at 05:08
  • You can use pattern HOC and use it in routes file. Example: . Or put Layout in component. – Vasyl Nahuliak Nov 27 '18 at 16:34
  • Sorry for the delay in the reply. I tried HOC method but it gives `Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.` and am not sure how to use the other one. Could you please clarify it? – kemakino Dec 12 '18 at 01:32
  • You need pass all props. Read this article https://medium.com/@soorajchandran/introduction-to-higher-order-components-hoc-in-react-383c9343a3aa – Vasyl Nahuliak Dec 12 '18 at 09:02