组件无法监听反应路由器

时间:2019-06-10 18:47:16

标签: javascript reactjs react-router-v4

我有一个可以在我的水疗中心永久使用的组件。我希望它能够知道我的路由器以及水疗中心所在的各种路径。有没有简单的方法可以做到这一点,或者我是否必须缠着总是在听路由器变化的redux(或类似的东西)状态解决方案?谢谢!您可以看到以下示例。

index.jsx:

import 'babel-polyfill';
import React from 'react';
import { render } from 'react-dom';
import { Provider } from 'react-redux';
import { ConnectedRouter } from 'connected-react-router';
import { Route, Switch } from 'react-router-dom';
import { history, store } from './redux/store';
import Navigation from './navigation';

const UserReport = () => <h2>User Report</h2>;

const UserPage = () => <h2>User Page</h2>;

const Routes = () => (
  <React.Fragment>
    <Route component={Navigation} />
    <Switch>
      <Route exact path="/users/:startDate" component={UserReport} />
      <Route exact path="/users/:userId" component={UserPage} />
    </Switch>
  </React.Fragment>
);

render(
  <Provider store={store}>
    <ConnectedRouter history={history}>
      <Routes />
    </ConnectedRouter>
  </Provider>, document.getElementById('app'),
);

navigation.jsx:

import React from 'react';
import { withRouter } from 'react-router-dom';

const Navigation = (props) => {
  console.log(props.match.path);
  // expected: "/users/:startDate"
  // received: "/"
  return (
    <h2>Navigation</h2>
  );
};

export default withRouter(Navigation);

2 个答案:

答案 0 :(得分:1)

由于Navigation路线未指定任何路径,因此它始终与您所处的路径匹配,但是match.path仅向您显示与导航匹配所需的最小路径。这就是为什么它总是/

您可以使用location.pathname,但它会为您提供匹配的值,而不是匹配的路径。

const Navigation = props => {
  console.log(props.location.pathname);
  // prints `/users/1` if you're on https://blah.com/users/1
  // prints `/users/hey` if you're on https://blah.com/users/hey
  return <h2>Navigation</h2>;
};

不确定您想要的是什么,但是如果您确实扩展了要实现的目标,也许我可以提供更多帮助。

此外,您到path="/users/:userId"的第二条路线使第一条路线黯然失色。意味着无法判断hey中的/users/heystartDate还是userId。您应该引入一条单独的路线,例如path="/users/page/:userId"

答案 1 :(得分:0)

I ended up using this react-router github discussion as my solution

我的实现示例:

index.jsx:

import 'babel-polyfill';
import React from 'react';
import { render } from 'react-dom';
import { Provider } from 'react-redux';
import { ConnectedRouter } from 'connected-react-router';
import { Route, Switch } from 'react-router-dom';
import { history, store } from './redux/store';
import Layout from './layout';

const home = () => <h2>Home Page</h2>;
const users = () => <h2>Users</h2>;
const userPage = () => <h2>User Page</h2>;

const layoutRender = component => route => <Layout component={component} route={route} />;

const Routes = () => (
  <Switch>
    <Route exact path="/" component={layoutRender(home)} />
    <Route exact path="/users" component={layoutRender(users)} />
    <Route exact path="/users/:id" component={layoutRender(userPage)} />
  </Switch>
);

render(
  <Provider store={store}>
    <ConnectedRouter history={history}>
      <Routes />
    </ConnectedRouter>
  </Provider>, document.getElementById('app'),
);

layout.jsx:

import React from 'react';

const Layout = (props) => {
  const {
    component: Component,
    route,
  } = props;

  return (
    <div>
      <h1>This is the layout</h1>
      <Component route={route} />
    </div>
  );
};

export default Layout;