Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Component not mounting: React-Router 1.0.0-rc1 + Redux

I have a small prototype using React, Redux and React-Router 1.0.0-rc1. The prototype uses Webpack to do code splitting. It currently uses getComponents and getChildRoutes to async load additional routes like so:

module.exports = {
  path: 'donations',

  getChildRoutes(location, cb) {
    require.ensure([], (require) => {
      cb(null, [
        require('./routes/Donation'),
      ]);
    });
  },

  getComponent(location, cb) {
    require.ensure([], (require) => {
      cb(null, require('./components/Donations'));
    });
  }
};

This work fine, until I hit the nested route donations/:id, which looks like:

module.exports = {
  path: ':id',

  getComponents (location, cb) {
    console.log('got it', cb); // debugging
    require.ensure([], (require) => {
      console.log('called it', cb); // debugging
      cb(null, require('./components/Donation'));
    });
  }
};

When I navigate to this route (ex: /donations/123), the route is triggered, the bundle.js file is loaded, and both console.logs appear in the console, so I know that the route was loaded up into memory. However, the component is not mounted and rendered.

Results of console.log:

got it function (error, value) {
      done(index, error, value);
    }
called it function (error, value) {
      done(index, error, value);
    }

Async routes one level deep are fine, but nesting past that doesn't work. The component is loaded, but it doesn't seem like it's executed.

The component that is returned is wrapped with Redux's Connect like so:

 function Connect(props, context) {
          _classCallCheck(this, Connect);
          _Component.call(this, props, context);
          this.version = version;
          this.store = props.store || c… 

Update: Problem solved

The issue was quite simple. Since this was a nested route, the Router was passing the nested component to its parent in this.props.children, which I wasn't checking for. Chalk it up to a mis-understanding of the (sparse) documentation for 1.0.0-rc1.

like image 479
Darren Newton Avatar asked Sep 24 '15 15:09

Darren Newton


1 Answers

I had a fundamental misunderstanding of how react-router works, in that when you're working with nested (child) routes the parent component needs to accommodate them as this.props.children:

Before

render() {
    let { DonationsComponent } = this.props
    return (
      <div>
        <h2>Donations</h2>
        <DonationsList donations={DonationsComponent} entities={entities} />
      </div>
    );
  }

In the above, render doesn't take into account this.props.children, so the nested route (Donation) was pulled in and connected, but not rendered.

render() {
    let { children, DonationsComponent, entities } = this.props
    let child = <DonationsList donations={DonationsComponent} entities={entities} />
    return (
      <div>
        <h2>Donations</h2>
        {children || child}
      </div>
    );
  }

Now, when react-router pulls in a nested route and passes it to this.props.children, the render function does the correct thing and renders children instead of child.

like image 151
Darren Newton Avatar answered Oct 06 '22 15:10

Darren Newton