我怀疑这就是问题所在:
component: React.cloneElement(child.props.component, {
child.props.component
不是渲染组件(如
<Dashbard />
),它是
组件类
(如
Dashboard
).
cloneElement
需要渲染组件。并且不能显式地将道具额外传递到
组件类
.
有几种方法可以实现你正在做的事情。克隆路线对我来说很“棘手”。
选项1:高阶组件
updateTitle
思维方式
我会亲自尝试
高阶分量
(一个接受组件类并返回组件类的函数),用于添加此道具,并导出包装在其中的仪表板/登录组件。稍微详细一点,但没有那么棘手:
临时文件:
const WithExtraProp = (ContentComponent) => {
return WithPropWrapper extends Component {
updateMenuTitle() {...}
render() {
// Add extra props here
return <ContentComponent {...this.props} functions={{ updateMenuTitle: this.updateMenuTitle }}/>
}
}
}
export default WithExtraProp;
和在仪表板中
class Dashboard extends Component {...}
export default WithExtraProp(Dashboard);
使用这种方法,您也可以这样做(尽管我不太喜欢)
<AppLayout>
<Route component={WithExtraProp(Dashboard)} path="/" key="/" />
<Route component={WithExtraProp(Login)} path="/login" key="/login" />
</AppLayout>
选项2:使用
<Route render={} />
而不是
component={}
添加道具
如果您想保持当前设置,您可以在其中隐式/神奇地添加道具
,我看不到不使用路线的方法
render
道具代替
component
. 这样,您可以正常渲染组件并传入道具。
您可以保持不变:
<Route component={Dashboard} path="/" key="/" />
像这样:
const childrenWithExtraProp = React.Children.map(this.props.children, (child) => {
// Clone the <Route />, remove the `component` prop, add `render` prop
return React.cloneElement(child, {
// Remove the `component` prop from the Route, since you can't use
// `component` and `render` on a Route together. This way component
// just becomes an API for this withExtraPropClass to use to find
// the right component
component: null,
render = () => {
const ChildComponent = child.props.component;
const functions = {
updateMenuTitle: this.updateTitle //function
};
return <ChildComponent functions={functions} />;
}
})
});
});
选项3:制造
AppLayout
高阶组件
这与选项1相同,最终您可以执行以下操作:
//imports omited
export default (
<Route component={Dashboard} path="/" key="/" />
<Route component={Login} path="/login" key="/login" />
);
和
应用布局
是添加道具的高阶组件。
const AppLayout = (ContentComponent) => {
return WithPropWrapper extends Component {
updateMenuTitle() {...}
render() {
// Add extra props here
return (
<MyLayoutStuff>
<ContentComponent {...this.props} functions={{ updateMenuTitle: this.updateMenuTitle }}/>
</MyLayoutStuff>
);
}
}
}
export default AppLayout;
并导出封装在布局中的组件:
class Dashboard extends Component {...}
export default AppLayout(Dashboard);
其他想法
我个人一直在使用与#3最接近的东西。具体来说,我有一个文件
dashboard/Dashboard.js
,并在同一文件夹中,
dashboard/index.js
,导出包装在布局中的仪表板。您可以在以下位置看到该模式的示例
this React boilerplate Github folder
.
还有其他选择。你可以
<AppRoutes children=[{component: Dashboard, path="/"}, {...}] />
不必处理克隆的组件。如果你需要和孩子一起做事情
<render>
我通常更喜欢将它们作为数组传递,而不是子组件和映射。