我正在尝试用react实现简单的CRUD功能,使用反应路由器进行不同的路由。
我的路线定义如下:
<Route path="locations" component={LocationPage}>
<IndexRoute component={LocationsView}/>
<Route path="create" component={LocationCreate}/>
<Route path=":locationSlug">
<IndexRoute component={LocationsView}/>
<Route path="edit" component={LocationEdit}/>
</Route>
</Route>
我在LocationPage
:
render() {
return (
<div>
<h1>Locations</h1>
{this.props.children}
</div>
);
}
这个问题是我无法将道具传递给每个子组件,即每个子组件都必须获取自己的状态来管理它。但这似乎很荒谬,因为很明显他们是一个逻辑单位,只有LocationPage
需要知道并保持任何地点的状态。理想情况下,我想将这些位置作为道具传递给子组件,但我不知道如何以这种方式做到这一点。
我在网上看过这样的例子:
<RouteHandler {...this.state}/>
这可以解决我的问题,但我似乎无法让这个工作。我认为它长期以来一直被贬低,因为互联网上关于它的大部分信息已经过时。
我没有真正意识到如何在没有克隆的魔法的情况下将道具传递给this.props.children
,并以此方式添加道具,但如果可能的话我想避免使用道具。
是否有任何建议的方法可以解决此问题?任何帮助将不胜感激。
答案 0 :(得分:0)
基本概念是遍历子项,克隆它们并插入当前组件的状态和道具。然后该函数返回cloned个孩子。见下文:
render: function () {
return (
<div>
<h1>Locations</h1>
{this._renderedChildren()}
</div>
);
},
_renderedChildren: function () {
var renderedChildren = React.Children.map(this.props.children,
function (child) {
return React.cloneElement(
child, Object.assign({}, this.state, this.props)
);
}.bind(this)
);
return renderedChildren;
}
Object.assign({}, this.state, this.props)
正在合并this.state和this.props。
React.cloneElement(child, props)
使用指定的道具制作新的反应元素。
答案 1 :(得分:0)
我最终只是实现了自己的RouteHandler
。实施:
export default (props) => {
// prevent childception
let propsToPass = {};
Object.keys(props).forEach(key =>
(key.localeCompare('children') !== 0) && (propsToPass[key] = props[key])
);
return <div>
{props.children && React.cloneElement(props.children, { ...propsToPass })}
</div>
}
用法:
render() {
return (
<div>
<h1>Locations</h1>
<RouteHandler
locations={this.props.locations}
selectedLocation={this.props.selectedLocation}>
{this.props.children}
</RouteHandler>
</div>
);
}
这实现了我想要的功能,而不会在代码中引入太多样板。希望如果有人遇到这个问题,这可能对某人有所帮助。
我最终没有真正使用它,因为最终,这个组件变得太大而且对我的喜好负有太多责任,所以我最终最终将处理逻辑移动到子组件中,这看起来像是两个邪恶中较少的一个。