如何确定反应路由器中的活动路由

时间:2016-08-21 22:22:20

标签: redux react-router

我有一个Redux应用程序,它使用带有嵌套路由的反应路由器,如下所示:

<Provider store={store}>
    <Router history={browserHistory}>
        <Route name="sales" path="/" component={App}>
          <IndexRoute name="home" component={Home} />
          <Route name="reports" path="/reports" component={Reports}>
            <IndexRoute name="reports-home" component={ReportsHome} />
          <Route name="report-1" path="/reports/report-1" component={Report1}/>
          <Route name="report-2" path="/reports/report-2" component={Report2}/>
          </Route>
        </Route>
    </Router>
</Provider>

我试图写一个面包屑组件;所以希望能够确定目前的路线。

我已将组件配置为使用react路由器提供的withRouter功能接收路由器:

Breadcrumbs = withRouter(Breadcrumbs);

这给了我一个如下所示的路由器对象:

Object {__v2_compatible__: true}
__v2_compatible__: true
createHref: createHref(location, query)
createKey: createKey()createLocation: createLocation(location)
createPath: createPath(location, query)
go: go(n)
goBack: goBack()
goForward: goForward()
isActive: isActive(location)
listen: listen(listener)
listenBefore: listenBefore(hook)
push: push(location)
pushState: ()
registerTransitionHook: registerTransitionHook(hook)
replace: replace(location)
replaceState: ()
setRouteLeaveHook: listenBeforeLeavingRoute(route, hook)
setState: ()
transitionTo: transitionTo(nextLocation)
unregisterTransitionHook: unregisterTransitionHook(hook)
__proto__: Object

我可以用它来确定当前路线吗?还有更好的办法吗?

2 个答案:

答案 0 :(得分:1)

通过withRouter获取位置等已添加到react-router 3.0版中。 Dan Abramov建议升级到3.0以使用withRouter。从2.7到3.0,它只提供你看到的功能。

来源:https://github.com/ReactTraining/react-router/blob/master/CHANGES.md#v300-alpha1

答案 1 :(得分:0)

已经有一个模块为您执行此操作,我相信它被称为react-router-breadcrumbs。我虽然没试过。

如果您需要自定义解决方案,请执行以下操作:

使用this.props.routesthis.props.params个对象。然后,您可以通过routes进行映射,并为每个条目在params对象中查找此类密钥。然后,您可以使用所述参数创建一个字符串。

请注意,我已经为每个路由(IndexRoutes除外)提供了path属性,因为有时我想为给定页面显示自定义名称。例如:

<Route path="/:productId" name="Start" title="Start" component={StartView} />

以下是我的应用上的解决方案:

componentDidMount = () => {
  this._prepareBreadCrumbs(this.props);
}

componentWillReceiveProps = (newProps) => {
  this._prepareBreadCrumbs(newProps);
}

_prepareBreadCrumbs = (props) => {
  let {routes, params} = props;
  let breadcrumbPath = "";
  let temp = routes.map(
    (item, i) => {
      if(item.path == null) return null; //if we are visiting an item without a path, ignore it.
      if(i < routes.length-1 && routes[i+1].path != null) {
        let arr = item.path.split(/[:/]|(:\/)/g); //sometimes the path is like "/:product_id/details" so I need to extract the interesting part here.
        arr = arr.map(function(obj) {
          return (obj in params) ? params[obj] : obj; //We now have ":product_id" and "details" - the first one will exist in the "params" object.
        });
        breadcrumbPath += arr.filter(Boolean).join("/") + "/";  //clean out some garbage and add the "/" between paths.
        if(i == 0) return <li key={i}><Link to={breadcrumbPath}>YourSite.com</Link></li>  //If on the root - display the site name
        return <li key={i}><Link to={breadcrumbPath}>{item.name}</Link></li>
      } else {
        document.title = "YourSite.com - " + item.title;  //set the document title if you want
        if(i == 0) return <li key={i} className="active"><span>YourSite.com</span></li>
        return <li key={i} className="active"><span>{item.name}</span></li>
      }
    }
  );
  this.setState({breadcrumbPath: temp});
}

render() {
  <p>{this.state.breadCrumbPath || ""}</p>
}

您希望将其放入顶级React组件中。