The Coder
The Coder

Reputation: 4007

alternative for IndexRoute in react-router 4

I am following a course where the author has written some code for routing in react using react-router version 3.

<Router history={browserHistory} >
  <Route path="/" component={Main}>
      <IndexRoute component={PhotoGrid}></IndexRoute>
      <Route path="/view/:postId" component={Single}>
   </Route>
</Router>

While following the course(in which I am using using router version 4), I came to know that now the <IndexRoute> doesn't exists. I googled for alternative and found that exact is the alternative. But I don't know how to use exact for meeting this requirement. The author want the Main component always on the DOM, and based on the url only the child components should change(i.e Single or PhotoGrid).
I tried below code, which is of course the wrong one:

 <BrowserRouter>
    <Switch>
      <Route path="/" component={Main} />
      <Route exact path="/" component={PhotoGrid} />
      <Route path="/veiw/:postId" component={Single} />
    </Switch>
  </BrowserRouter>    

My components are:

class Main extends React.Component {
  render() {
    return (
        <div>
          <h1>
            <Link to="/">Reduxtagram</Link>
          </h1>
          {React.cloneElement(this.props.children, this.props)}
        </div>           
    );
  }
}

class PhotoGrid extends React.Component {
  render() {
    return <div className="photo-grid">PhotoGrid</div>;
  }
}

class Single extends React.Component {
  render() {
    return <div className="single-photo">Single</div>;
  }
}

Upvotes: 3

Views: 3788

Answers (2)

Oliver Lluberes
Oliver Lluberes

Reputation: 1

i know this is an old question but im following the same course and i decided to update all the libraries, basically i had to restructure the app like this:

reduxtagram.js :

import React from 'react';
import {render} from 'react-dom';
import App from './components/App';
import {Provider} from 'react-redux';
import store from './store';
// import css
import css from './styles/style.styl';

// import react router deps

const router = (
    <Provider store={store}>
      <App/>
    </Provider>
)

render(router , document.getElementById('root'));

main.js:

import React, { Component } from 'react';
import {Link} from 'react-router-dom';
import PhotoGrid from './PhotoGrid';
import Single from './Single';
import {Router, Route} from 'react-router-dom';
import {history} from '../store';

export default class Main extends Component {
render() {
    return (
        <div>
            <Router history={history}>
                <Route
                path="/"
                render={(routeProps) => (
                    <h1>
                        <Link to='/'>Reduxstagram </Link>
                    </h1>
                )}/>

                <Route
                path="/grid"
                render={(routeProps) => (
                    <PhotoGrid {...routeProps} {...this.props} />
                )}/>

                <Route
                path="/grid/view/:postID"
                render={(routeProps) => (
                    <Single {...routeProps} {...this.props} />
                )}/>

            </Router>
        </div>
    )
    }
}

Upvotes: 0

Tholle
Tholle

Reputation: 112777

The Switch component will only render the first Route that is a match.

You could use the Main component as a regular component and use the Switch as children for that.

<BrowserRouter>
  <Main>
    <Switch>
      <Route exact path="/" component={PhotoGrid} />
      <Route path="/view/:postId" component={Single} />
    </Switch>
  </Main>
</BrowserRouter>

Upvotes: 2

Related Questions