根据路线将道具传递给React组件

时间:2017-11-01 20:28:00

标签: reactjs react-router

我有一个使用react-router的根组件:

<HashRouter>
  <aside>
    <Sidebar />
  </aside>
  <main>
    <Switch>
      {/* -- routes go here -- */}
    </Switch>
  </main>
</HashRouter>

我希望我的Sidebar组件具有不同的内容,具体取决于我们所依赖的路线。因此,如果我有foobar这两条路线,那么当我转到/foo时,我希望Sidebar拥有与我访问/bar时不同的道具。我已经尝试将location作为道具传递:

<Sidebar location={this.context.router.location.pathname} />

但我非常确定它的工作方式并非如此......果然它确实无法运作。

2 个答案:

答案 0 :(得分:1)

您可以使用withRouter将值从路由传递到另一个组件。这样,您可以执行条件渲染或实现与组件的当前路径相关的任何其他逻辑。

  

您可以访问历史对象的属性和最近的属性   通过withRouter高阶组件进行匹配。 withRouter   每当路线改变时,它将重新渲染其组件   与渲染道具相同的道具:{匹配,位置,历史}。

示例 (来自官方文档)

// A simple component that shows the pathname of the current location
class ShowTheLocation extends React.Component {
  static propTypes = {
    match: PropTypes.object.isRequired,
    location: PropTypes.object.isRequired,
    history: PropTypes.object.isRequired
  }

  render() {
    const { match, location, history } = this.props

    return (
      <div>You are now at {location.pathname}</div>
    )
  }
}

// Create a new component that is "connected" (to borrow redux
// terminology) to the router.
const ShowTheLocationWithRouter = withRouter(ShowTheLocation)

答案 1 :(得分:1)

这是使用React Router的withRouter<Sidebar />组件“连接”到路由器的方法。

使用withRouter我们正常创建<Sidebar />组件,然后像这样'连接':

//Sidebar
class Sidebar extends React.Component {
  render() {
    const { location } = this.props;

    return (
      <div>
        <h1>Sidebar</h1> 
        <p>You are now at {this.props.location.pathname}</p>
      </div>
    )
  }
}

const SidebarWithRouter = withRouter(Sidebar);

最后,我们有一个新的<SidebarWithRouter />组件连接到路由器,因此它可以访问matchlocationhistory

不幸的是,由于iframe中的history,代码段在Stackoverflow中不起作用,但这是代码,并且工作正常Codepen

let { BrowserRouter, Link, Route } = ReactRouterDOM;
let { Switch, withRouter } = ReactRouter;
let Router = BrowserRouter;

// App
class App extends React.Component {
  render() {
    return (
      <Router>
        <div className="container">
          <ul>
            <li>
              <Link to="/">Home</Link>
            </li>
            <li>
              <Link to="/about">About</Link>
            </li>
          </ul>
          <hr />
          <aside>
            <SidebarWithRouter  />
          </aside>
          <Switch> 
            <Route exact path="/" component={Home} />
            <Route path="/about" component={About} />
          </Switch>
        </div>
      </Router>
    );
  }
}

//Home
const Home = () => (
  <div>
    <h1>Home</h1>
    <p>This is the Home Page.</p>
  </div>
);

//About
const About = () => (
  <div>
    <h1>About</h1>
    <p>This is about</p>
  </div>
);

//Sidebar
class Sidebar extends React.Component {
  render() {
    const { location } = this.props;

    return (
      <div>
        <h1>Sidebar</h1> 
        <p>You are now at {this.props.location.pathname}</p>
      </div>
    )
  }
}

const SidebarWithRouter = withRouter(Sidebar);

ReactDOM.render(<App />, document.getElementById("app"));