我有以下结构为我的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路由器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 v4 alpha

现在有了一种新的方法,尽管和之前的方法很相似。

import { Match, Link, Miss } from 'react-router';
import Homepage from './containers/Homepage';

const route = {
    exactly: true,
    pattern: '/',
    title: `${siteTitle} - homepage`,
    component: Homepage
  }

<Match { ...route } render={(props) => <route.component {...props} />} />

附注:这只适用于alpha版本,并且在v4 alpha发布后被删除。在v4 latest中,同样是带有路径和精确props的。

React-lego是一个示例应用程序,它在react-router-4分支的routes.js中包含了这样做的代码

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

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

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

更多参考:React Router v5.1

在1.0和2.0中,你可以使用Router的createElement道具来指定如何创建目标元素。文档来源

function createWithDefaultProps(Component, props) {
    return <Component {...props} myprop="value" />;
}

// and then    
<Router createElement={createWithDefaultProps}>
    ...
</Router>

更新

自新版本以来,可以直接通过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);
});

使用自定义路由组件,这在React Router v3中是可能的。

var Dashboard = require('./Dashboard');
var Comments = require('./Comments');
var routes = (
  <Route path="/" handler={Index}>
    <MyRoute myprop="value" path="comments" handler={Comments}/>
    <DefaultRoute handler={Dashboard}/>
  </Route>
);

对于<MyRoute>组件代码,它应该类似于:

import React from 'react';
import { Route } from 'react-router';
import { createRoutesFromReactChildren } from 'react-router/lib//RouteUtils';

const MyRoute = () => <div>&lt;MyRoute&gt; elements are for configuration only and should not be rendered</div>;

MyRoute.createRouteFromReactElement = (element, parentRoute) => {
    const { path, myprop } = element.props;
    // dynamically add crud route
    const myRoute = createRoutesFromReactChildren(
        <Route path={path} />,
        parentRoute
    )[0];
    // higher-order component to pass myprop as resource to components
    myRoute.component = ({ children }) => (
        <div>
            {React.Children.map(children, child => React.cloneElement(child, { myprop }))}
        </div>
    );
    return myRoute;
};

export default MyRoute;

有关自定义路由组件方法的更多详细信息,请查看我关于该主题的博客文章:http://marmelab.com/blog/2016/09/20/custom-react-router-component.html