简体   繁体   English

如何通过this.props.children将道具从父母传递给孩子?

[英]How can I pass props from a Parent to Child with this.props.children?

I have difficulties trying to pass props to this.props.children 我很难将道具传递给this.props.children

I have a component MainLayout and I would like to pass props to this.props.children but his children are like that : 我有一个MainLayout组件,我想将props传递给this.props.children,但他的孩子们是这样的:

AppRouter.js AppRouter.js

export default class AppRouter extends Component {

  render() {

    return (
      <HashRouter>
        <Switch>
          <MainLayout>
            <Route exact path="/" component={PubsList} />
            <Route exact path="/add-pub" component={AddPub} />
            <Route exact path="/add-pub/:id" component={AddPub} />
          </MainLayout>
        </Switch>
      </HashRouter>
    )
  }
}

MainLayout.js : I used React.Children and React.CloneElement to pass props MainLayout.js:我使用React.Children和React.CloneElement传递道具

export default class MainLayout extends Component {

 constructor(props) {
  super(props);
  this.state = {
   foo: "foo"
  };

  render() {

    return (
      <div className="container" >
        <Menu inverted color='teal' fixed="top" style={{ margin: "0", padding: "20px", borderRadius: "0", display: "block" }}>    
          <Link to="/">
            <Header as='h2' content='PandaBar' floated="left" style={{ color: "white", margin: "0" }} />
          </Link>    
        </Menu>    

        <div className="content" style={{ marginTop: "70px", overflow: "hidden" }} >    

          {React.Children.map(this.props.children, child => {
           return React.cloneElement(child, { foo: this.state.foo })
          })}    

        </div>
      </div>
    );
  }
}

But, once my routes get the props, it appears like this: 但是,一旦我的路线获得了道具,它就会像这样:

<HashRouter>
   <Switch>
     <MainLayout>
        <Route exact path="/" component={PubsList} foo="foo"/>
        <Route exact path="/add-pub" component={AddPub} foo="foo"/>
        <Route exact path="/add-pub/:id" component={AddPub} foo="foo"/>
     </MainLayout>
    </Switch>
</HashRouter>

So, how can I pass my props foo to my component PubsList and AddPub with this configuration ? 那么,如何通过这种配置将props foo传递给组件PubsList和AddPub呢?

Route does provide a way to pass custom props to the component, by using the render prop instead of the component prop. 路线确实提供了一种方式来传递自定义道具的组件,通过render道具,而不是component道具。 You pass a function in to the render prop, and that function will get called with the same props that are normally automatically passed when using component . 您将一个函数传递给render prop,该函数将使用通常使用component时自动传递的相同prop来调用。 You can then do whatever you want to with those props 然后,您可以使用这些道具做任何您想做的事

An example of this (not including your mainLayout component) would look like this: 这样的一个示例(不包括mainLayout组件)如下所示:

<Route render={(routeProps) => (
  <PubsList hello="world" {...routeProps} />
)}/>

So using this, you can put arbitrary props onto the components. 因此,使用此工具,您可以在组件上放置任意道具。 But then how to let MainLayout dictate what those extra props are? 但是然后如何让MainLayout指示那些额外的道具是什么? There i think you'll need to modify MainLayout to have a render prop of its own. 我认为您需要修改MainLayout才能拥有自己的渲染道具。

render() {
  let children = null;
  if (this.props.render) {
    children = this.props.render({ foo: this.state.foo })
  }

  return (
    <div className="container" >
      <Menu inverted color='teal' fixed="top" style={{ margin: "0", padding: "20px", borderRadius: "0", display: "block" }}>    
        <Link to="/">
          <Header as='h2' content='PandaBar' floated="left" style={{ color: "white", margin: "0" }} />
        </Link>    
      </Menu>    

      <div className="content" style={{ marginTop: "70px", overflow: "hidden" }} >    
        {children}
      </div>
    </div>
  );
}

And you would use it like this: 您将像这样使用它:

<MainLayout render={(layoutProps) => (
  <React.Fragment>
    <Route exact path="/" render={(routeProps) => 
      <PubsList {...layoutProps} {...routeProps} />
    }/>
    <Route exact path="/add-pub" render={(routeProps) => 
      <AddPub {...layoutProps} {...routeProps} />
    }/>
    <Route exact path="/add-pub/:id" render={(routeProps) => 
      <AddPub {...layoutProps} {...routeProps} />
    }/>
  </React.Fragment>
)} />

In the example foo prop is passed to wrong component ( Route ). 在示例中, foo prop被传递到错误的组件( Route )。

In order to be passed to route components, route component prop should be changed instead: 为了传递给路由组件,应该改为更改路由component prop:

const withFoo = (Comp, foo) => props => <Comp {...props} foo={foo}/>;
...

  render() {

    return (
      ...
      {React.Children.map(this.props.children, route => {
        return React.cloneElement(route, {
          component: withFoo(route.props.component, this.state.foo)
        });
      })}    
      ...
    );
  }

While the use of Route render prop as another answer suggest may be more straightforward. 虽然使用Route render prop作为另一个答案可能更直接。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM