发送道具以响应父布局组件中的路由器组件

时间:2018-08-04 08:42:32

标签: reactjs react-router

我创建了一个名为Main的布局组件,该组件使用React.cloneElement(children, { user: 'First Name'})将用户道具发送到其子组件,但是无法将该用户道具传递给Route组件。

  

index.js

import React from "react";
import ReactDOM from "react-dom";
import { BrowserRouter as Router, Route } from "react-router-dom";
import Main from "./Main.jsx";
import Home from "./Home.jsx";

const App = () => (
  <Router>
    <Main>
      <Route
        path="/"
        render={props => {
          return <Home {...props} />;
        }}
      />
    </Main>
  </Router>
);

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
  

Main.jsx

import React from "react";

export default props => {
  return <div>{React.cloneElement(props.children, { user: "Username" })}</div>;
};
  

Home.jsx

import React from "react";

export default props => {
  const { user } = props;
  return <div>User - {user}</div>;
};

但无法在user组件中获得Home道具。如果我不使用Route,那么它将传递给Home

执行此操作时,Home会收到user个道具。

<Main>
   <Home />
</Main>

如何获取user道具并将其发送到Route渲染的组件?

方案的Codesandox链接-https://codesandbox.io/s/kmyrj0zr8o

2 个答案:

答案 0 :(得分:1)

好吧,您必须将Route包装到自己的组件中。这个想法是捕获道具并将其手动传递到Route的{​​{1}}。

此处已修改为来源:https://codesandbox.io/s/zx508v60yl

包装renderRoute

MyRoute.jsx

修改import React from "react"; import { Route } from "react-router-dom"; export default class MyRoute extends React.Component { render() { var { Component, path, exact, passedProps } = this.props; return ( <Route path={path} exact={exact} render={props => <Component {...props} {...passedProps} />} /> ); } }

Main.jsx

然后将import React from "react"; export default props => { return ( <div> {React.cloneElement(props.children, { passedProps: { user: "Username" } })} </div> ); }; 中的Route更改为MyRoute

index.js

答案 1 :(得分:0)

当您需要将道具传递给路由器组件时,您需要使用render prop来做到这一点,但是由于React.cloneElement实际上只是将道具传递给Route组件,因此您可以编写Route周围的包装,类似

const RouteWrapper = ({render, exact, strict, path, ...rest}) => {
     return (
          <Route 
              exact={exact}
              strict={strict}
              path={path}
              render={(function(routerProps) => { 
                    return render(...routerProps, ...rest)
              })()}
          />
     )
}

您现在可以使用like

const App = () => (
  <Router>
    <Main>
      <RouteWrapper
        path="/"
        render={props => {
          return <Home {...props} />;
        }}
      />
    </Main>
  </Router>
);