jordan.baucke
jordan.baucke

Reputation: 4328

Render React Component based on React-Route

I am trying to render a specific component inside of another component based on React, React-Router v4, and Redux in my main 'panel' wrapped in a fixed header and sidebar component.

For example when I select an item from the sidebar, I to render the Detail panel and and load the details based on the id, like: <Route path='/item/:id' component={ItemDetail} />

Outline navigating React-Router

routes.js

  import React, { Component } from 'react';
    import { RouteHandler, Switch, Route, DefaultRoute } from 'react-router';
    import App from './containers/App';
    import Login from './containers/Login';
    import LobbyDetail from './components/LobbyDetail';
    export default (
      <Switch>
        <Route exact path="/" component={App} />
        <Route exact path="/login" component={Login} />
      </Switch>
    );

app.js:

import React, { Component } from 'react'
import { Router, Route, Link } from 'react-router'
import { connect } from 'react-redux'
import PropTypes from 'prop-types';
import auth from '../actions/auth';
import Sidebar from '../Components/Sidebar'

class App extends Component {
    static propTypes = {
    };

    /**
     * 
     */
    render() {
        const { ... } = this.props
        return (
            <div className="container-fluid">
                <div className="row">
                    {* I WANT TO RENDER DYNAMIC COMPONENT HERE *}
                </div>
                <Sidebar currentUser={currentUser}
                    logout={logout}
                    />
            </div>
        );
    }
}

// ...

export default connect(mapStateToProps, mapDispatchToProps)(App)

index.js (basically main app):

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { ConnectedRouter } from 'react-router-redux';
import { createMemoryHistory } from 'history';
import routes from './routes';
import configureStore from './store/store.js';
import { AppContainer } from 'react-hot-loader';

const syncHistoryWithStore = (store, history) => {
  const { routing } = store.getState();
  if (routing && routing.location) {
    history.replace(routing.location);
  }
};

const initialState = {};
const routerHistory = createMemoryHistory();
const store = configureStore(initialState, routerHistory);
syncHistoryWithStore(store, routerHistory);

const rootElement = document.querySelector(document.currentScript.getAttribute('data-container'));

const render = () => {

  ReactDOM.render(
    <AppContainer>
      <Provider store={store}>
        <ConnectedRouter history={routerHistory}>
          {routes}
        </ConnectedRouter>
      </Provider>
    </AppContainer>,
    rootElement
  );
}

render();

if (module.hot) { module.hot.accept(render); }

Upvotes: 1

Views: 5860

Answers (1)

Kyle Richardson
Kyle Richardson

Reputation: 5645

What you're looking for is parameterized routing. Make a <Route/> like the following: <Route path='/item/:id' component={ MyComponent } />.

Now in MyComponent you can use the value of props.match.params.id to conditionally render, or if you're trying to load async data based on the value of :id; You can use the componentWillReceiveProps life cycle method and dispatch an action based on the value of this.props.match.params.id.

Note: <Link to='/item/some-item'/> will set the value of match.params.id to 'some-item'.

Upvotes: 2

Related Questions