我有以下结构为我的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路由器最简单和正确的方法是什么?


当前回答

这是我想出的最干净的解决方案(React Router v4):

<Route
  path="/"
  component={props => <MyComponent {...props} foo="lol" />}
/>

MyComponent仍然有道具。火柴和道具。位置,并有道具。Foo === "lol"。

其他回答

更新

自新版本以来,可以直接通过Route组件传递道具,而不使用Wrapper。例如,通过使用渲染道具。

组件:

class Greeting extends React.Component {
  render() {
    const {text, match: {params}} = this.props;

    const {name} = params;

    return (
      <React.Fragment>
        <h1>Greeting page</h1>
        <p>
          {text} {name}
        </p>
      </React.Fragment>
    );
  }
}

用法:

<Route path="/greeting/:name" render={(props) => <Greeting text="Hello, " {...props} />} />

Codesandbox例子


旧版本

我更喜欢的方法是包装Comments组件,并将包装器作为路由处理程序传递。

这是应用更改后的示例:

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

var CommentsWrapper = React.createClass({
  render: function () {
    return (
      <Comments myprop="myvalue"/>
    );
  }
});

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

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

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

你也可以使用RouteHandler mixin来避免包装器组件,更容易地将父类的状态作为道具传递下去:

var Dashboard = require('./Dashboard');
var Comments = require('./Comments');
var RouteHandler = require('react-router/modules/mixins/RouteHandler');

var Index = React.createClass({
      mixins: [RouteHandler],
      render: function () {
        var handler = this.getRouteHandler({ myProp: 'value'});
        return (
            <div>
                <header>Some header</header>
                {handler}
           </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);
});

React路由器v5.1 (React >= 16.8)这样做的方式:

<Route path="/comments">
    <Comments myprop="value" />
</Route>

现在,如果你想访问组件中的Route Props,你可以参考这个解决方案。对于函数组件,还有另一个钩子useParams()在那篇文章中没有提到。

更多参考:React Router v5.1

对于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'})}
  )
}
...

你可以像这样通过<RouterHandler/>传入props:

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

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

这样做的缺点是你不加区别地传递道具。因此,Comments可能最终接收到的道具实际上是针对不同组件的,这取决于您的路由配置。这不是什么大问题,因为props是不可变的,但如果两个不同的组件都期望一个名为foo的道具,但值不同,这就会出现问题。