我有以下结构为我的React.js应用程序使用React路由器:

var Dashboard = require('./Dashboard');
var Comments = require('./Comments');

var Index = React.createClass({
  render: function () {
    return (
        <div>
            <header>Some header</header>
            <RouteHandler />
        </div>
    );
  }
});

var routes = (
  <Route path="/" handler={Index}>
    <Route path="comments" handler={Comments}/>
    <DefaultRoute handler={Dashboard}/>
  </Route>
);

ReactRouter.run(routes, function (Handler) {
  React.render(<Handler/>, document.body);
});

我想把一些属性传递给Comments组件。

(通常我会这样做,如<Comments myprop="value" />)

用React路由器最简单和正确的方法是什么?


当前回答

反应路由器v 4解决方案

今天早些时候我偶然发现了这个问题,下面是我使用的模式。希望这对那些正在寻找最新解决方案的人有用。

我不确定这是否是最好的解决方案,但这是我目前的模式。我通常有一个核心目录,我保存我常用的组件及其相关配置(加载器,模态等),我包括一个这样的文件:

import React from 'react'
import { Route } from 'react-router-dom'

const getLocationAwareComponent = (component) => (props) => (
  <Route render={(routeProps) => React.createElement(component, 
{...routeProps, ...props})}/>
)

export default getLocationAwareComponent

然后,在有问题的文件中,我将执行以下操作:

import React from 'react'
import someComponent from 'components/SomeComponent'
import { getLocationAwareComponent } from 'components/Core/getLocationAwareComponent'
const SomeComponent = getLocationAwareComponent(someComponent)

// in render method:
<SomeComponent someProp={value} />

您会注意到我将组件的默认导出导入为humble camel-case,这让我可以在CamelCase中命名新的位置感知组件,以便正常使用它。除了额外的导入行和赋值行之外,组件的行为与预期一致,并正常接收它的所有道具,并添加了所有路由道具。因此,我可以愉快地使用this.props.history.push()重定向组件生命周期方法,检查位置等。

希望这能有所帮助!

其他回答

只是ColCh回答的一个后续问题。抽象一个组件的包装是很容易的:

var React = require('react');

var wrapComponent = function(Component, props) {
  return React.createClass({
    render: function() {
      return React.createElement(Component, props);
    }
  });
};

<Route path="comments" handler={wrapComponent(Comments, {myprop: value})}/>

我还没有测试这个解决方案,所以任何反馈都很重要。

需要注意的是,使用这种方法,任何通过Router发送的道具(比如params)都会被覆盖/删除。

这是来自Rajesh的解决方案,没有yuji的不便评论,并为React Router 4更新。

代码是这样的:

<Route path="comments" render={(props) => <Comments myProp="value" {...props}/>}/>

注意,我使用渲染而不是组件。原因是为了避免不必要的重新挂载。我还将道具传递给该方法,并在Comments组件上使用对象展开操作符(ES7建议)。

你可以通过将它们传递给<RouteHandler>(在v0.13.x中)或v1.0中的Route组件本身来传递道具;

// v0.13.x
<RouteHandler/>
<RouteHandler someExtraProp={something}/>

// v1.0
{this.props.children}
{React.cloneElement(this.props.children, {someExtraProp: something })}

(来自https://github.com/rackt/react-router/releases/tag/v1.0.0的升级指南)

所有子处理程序都将收到相同的一组道具——这可能有用,也可能没用,取决于具体情况。

对于react路由器2.x。

const WrappedComponent = (Container, propsToPass, { children }) => <Container {...propsToPass}>{children}</Container>;

在你的路线上…

<Route path="/" component={WrappedComponent.bind(null, LayoutContainer, { someProp })}>
</Route>

确保第3个参数是一个类似于:{checked: false}的对象。

对于react-router 2.5.2,解决方案非常简单:

    //someConponent
...
render:function(){
  return (
    <h1>This is the parent component who pass the prop to this.props.children</h1>
    {this.props.children && React.cloneElement(this.props.children,{myProp:'value'})}
  )
}
...