如何使用 this.props.children 将道具从父级传递给孩子?



我在尝试将道具传递给this.props.children时遇到困难

我有一个组件 MainLayout,我想将 props 传递给 this.props.children,但他的孩子是这样的:

应用路由器.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 : 我使用 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>
);
}
}

但是,一旦我的路线得到了道具,它就会看起来像这样:

<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>

那么,如何使用此配置将我的道具 foo 传递给我的组件 PubsList 和 AddPub ?

在示例中fooprop 被传递给错误的组件 (Route(。

为了传递给路由组件,应改为更改路由componentprop:

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)
});
})}    
...
);
}

虽然使用Route渲染道具作为另一个答案可能更直接。

Route 确实提供了一种将自定义 props 传递给组件的方法,通过使用renderprop 而不是componentprop。您将一个函数传递给renderprop,该函数将使用使用component时通常自动传递的相同 prop 进行调用。然后,您可以使用这些道具做任何您想做的事情

这方面的一个例子(不包括你的mainLayout组件(看起来像这样:

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

所以使用它,你可以把任意的道具放到组件上。但是,如何让 MainLayout 决定这些额外的道具是什么呢?在那里,我认为您需要修改 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>
);
}

你会像这样使用它:

<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>
)} />

最新更新