将道具传递给主动反应路由器处理程序

时间:2016-02-28 19:34:16

标签: javascript reactjs react-router

我正在尝试用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,并以此方式添加道具,但如果可能的话我想避免使用道具。

是否有任何建议的方法可以解决此问题?任何帮助将不胜感激。

2 个答案:

答案 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>
  );
}

这实现了我想要的功能,而不会在代码中引入太多样板。希望如果有人遇到这个问题,这可能对某人有所帮助。

我最终没有真正使用它,因为最终,这个组件变得太大而且对我的喜好负有太多责任,所以我最终最终将处理逻辑移动到子组件中,这看起来像是两个邪恶中较少的一个。