简体   繁体   中英

Child route handled by the same parent's component using react router

I'm trying to define the routes for a paginated application.

/           -> handled by App
/page/:page -> also handled by App

These are what my routes look like:

var routes = (
    <Route name="app" path="/" handler={App}>
        <Route name="paginated" path="page/:page" handler={App} />
    </Route>
);

This is what App looks like:

var App = React.createClass({
    render : function() {
        return (
            <div>
                <RouteHandler/>
                Something...
            </div>
        );
    }
});

The problem here is that, as paginated is an app 's child route, that Something... in the componet gets rendered twice.

What I'm trying to acomplish here is to default to page 1 for the app route and to load the desired page for the paginated route, without loading twice.

Any way to do this?

Using the App handler twice works the way you expect - it calls App twice. However, the parent should only be used as the parent twice. However, the parent should only be used as the parent Route Handler , and the children use their own Handlers`.

To get the initial page to load properly, use a DefaultRoute for the base path:

routes

var routes = (
    <Route name="app" path="/" handler={App}>
        <DefaultRoute handler={Home}/>
        <Route name="paginated" path="page/:page" handler={Page} />
    </Route>
);

app

var App = React.createClass({
    render : function() {
        return (
            <div>
                <RouteHandler/>
            </div>
        );
    }
});

home

var Home = React.createClass({
    render : function() {
        return (
            <div>
                ...Something...
            </div>
        );
    }
});

page

var Page = React.createClass({
    render : function() {
        return (
            <div>
                ...Something Completely Different...
            </div>
        );
    }
});

The React Router Default Handler Docs have a more substantial example:

<Route path="/" handler={App}>

  <!--
    When the url is `/`, this route will be active. In other
    words, `Home` will be the `<RouteHandler/>` in `App`.
  -->
  <DefaultRoute handler={Home}/>

  <Route name="about" handler={About}/>
  <Route name="users" handler={Users}>
    <Route name="user" handler={User} path="/user/:id"/>

    <!-- when the url is `/users`, this will be active -->
    <DefaultRoute name="users-index" handler={UsersIndex}/>

  </Route>
</Route>

Notice here that <Route name="user" handler={User} path="/user/:id"/> also has a default route, so when there is no :id match it has somewhere to go.

Hope this helps!

At the end I came up with a solution using a redirection that allowed me to have the pagination and nested routes in the paginated one.

var routes = (
    <Route name="app" path="/" handler={App}>
        <Redirect from="/" to="paginated" params={{ page : 1 }} />

        <Route name="paginated" path="page/:page" handler={PaginationLoader} />
    </Route>
);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM