mahars
mahars

Reputation: 41

React Router v4 ConnectedRouter is not rendering on nested routes

The first level routes are rendered correctly from Layout.tsx but on ResourcesUI.tsx is not rendered when is clicked (see code below).

ResourceUI component have 2 sections. the left section have links and right section have component that when links from the left is clicked, the right component should be rendered accordingly.

Like I said above, the resource component is routed correctly but the inside the resource component is not rendering when is clicked.

index.tsx

ReactDOM.render(
    <Provider store={store} >
        <ConnectedRouter  history={history} >
            <Layout />
        </ConnectedRouter>
    </Provider>,
    document.getElementById("root")
);

Layout.tsx

import routes from "routes"

<div className="container-fluid">
    <div className="row">
         <div className="col-sm-3">
              <SidebarContainer />
          </div>
         <div className='col-sm-9'>
              <Route exact path="/" component={Welcome} />
              <Route exact path="/services/:id" component={ServiceDetailsContainer} />
              <Route exact path="/services/:id/resources" component={ResourceContainer} />
         </div>
    </div>
    <div id="modal-root">
        <ModalContainer />
    </div>
</div>

ResourceContainer.tsx

class ResourceContainer extends React.Component<any & RouteComponentProps<{}>>{
    render() {
        const service = this.props.services.find(x => this.props.match.params.id === x.Id.toString());
        return (
            <ResourcesUI service={service} resources={service.Resources} match={this.props.match}/>
        );
    }
}

function mapStateToProps(state: AppState) {
    return {
        services: state.services.serviceRecords
    }
}
export default connect(mapStateToProps, null)(ResourceContainer);

ResourcesUI.tsx

class ResourcesUI extends React.Component<any & RouteComponentProps<{}>> {

    render() {
        return (
            <section>    
                <div className="container-fluid">
                    <div className="row">
                        <div className="col-sm-3">
                            <div className="panel panel-default">
                                <div className="panel-body">
                                    <ul>
                                        {
                                            this.props.resources.map(x => {
                                              // /services/:id/resources/:resourceId  
                                              const path = `${this.props.match.url}/${x.Id}`; 

                                                return (
                                                    <li key={x.Id}>
                                                        <NavLink to={path}>
                                                            {x.Name}
                                                        </NavLink>
                                                    </li>
                                                );
                                            })
                                        }
                                   </ul>
                                </div>
                            </div>
                        </div>

                        <div className="col-sm-9">
                            // THIS ROUTE IS NOT RENDERED WHEN LINK ABOVE IS CLICKED
                           // /services/:id/resources/:resourceId
                            <Route path={`${this.props.match.path}/:resourceId`} component={detailfoo} />
                        </div>
                    </div>
                </div>
            </section>
            );
    }
}

const detailfoo = () => (
    <section>
        <div className="panel panel-default">
            <div className="panel-body text-center">
                Hey yo!
            </div>
        </div>
        <div className="panel panel-default">
            <div className="panel-body">
                Hey yo!
            </div>
        </div>
    </section>
);

export default  ResourcesUI;

UPDATE

I had to add the nested route in the parent layout.tsx as well to make this work. If some one has better solution let me know. :)

<Route exact path="/services/:id/resources" component={ResourceContainer} />
<Route exact path="/services/:id/resources/:resourceId" component= ResourceContainer} />

Upvotes: 0

Views: 698

Answers (1)

Gavin Thomas
Gavin Thomas

Reputation: 1867

You should wrap your resources comp with withRouter. This will allow non direct descendants of your Router to have navigation props.

export default withRouter(MyComponent)

https://reacttraining.com/react-router/web/api/withRouter

Upvotes: 1

Related Questions