364

React Routerを使用した React.js アプリケーションの構造は次のとおりです。

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 Router でこれを行う最も簡単で正しい方法は何ですか?

4

26 に答える 26

191

アップデート

Route新しいリリース以降、Wrapper を使用せずに、コンポーネントを介して直接 props を渡すことが可能になりました。たとえば、propを使用しrenderます。

成分:

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} />} />

コードサンドボックスの例


古いバージョン

私の好みの方法は、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);
});
于 2015-01-09T20:18:54.090 に答える
125

受け入れられた応答のcianticによるコメントからのコピー:

<Route path="comments" component={() => (<Comments myProp="value" />)}/>

これは私の意見では最も優雅な解決策です。できます。助けて頂きました。

于 2016-08-18T20:44:34.023 に答える
12

ステートレス関数コンポーネントでラップします。

<Router>
  <Route 
    path='/' 
    component={({children}) => 
      <MyComponent myProp={'myVal'}>{children}</MyComponent/>
    }/>
</Router>
于 2016-05-14T21:35:22.657 に答える
11

次のように小道具を渡すことができます<RouterHandler/>

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 を受け取ることになる場合があります。は不変であるため大したことではありませんpropsが、2 つの異なるコンポーネントが名前が付けられているが値が異なる prop を期待している場合、これは問題になる可能性がありfooます。

于 2015-03-27T19:10:04.390 に答える
9

1.0 および 2.0 では、createElementprop ofRouterを使用して、ターゲット要素を作成する方法を正確に指定できます。ドキュメントのソース

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

// and then    
<Router createElement={createWithDefaultProps}>
    ...
</Router>
于 2016-02-11T10:42:42.120 に答える
7

React Router v 4 ソリューション

今日、この質問に出くわしました。これが私が使用するパターンです。これが、より最新のソリューションを探している人にとって役立つことを願っています。

これが最善の解決策かどうかはわかりませんが、これが私の現在のパターンです。通常、よく使用するコンポーネントと関連する構成 (ローダー、モーダルなど) を保持する Core ディレクトリがあり、次のようなファイルを含めます。

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} />

コンポーネントのデフォルトのエクスポートを謙虚なキャメルケースとしてインポートしていることに気付くでしょう。これにより、キャメルケースで新しい位置認識コンポーネントに名前を付けることができるので、通常どおり使用できます。追加の import 行と割り当て行を除いて、コンポーネントは期待どおりに動作し、すべてのルート props を追加して、すべての props を正常に受け取ります。したがって、this.props.history.push() を使用してコンポーネントのライフサイクル メソッドから喜んでリダイレクトしたり、場所を確認したりできます。

お役に立てれば!

于 2017-06-22T20:21:19.303 に答える
5

es6 とステートレス関数を組み合わせて、よりクリーンな結果を得ることができます。

import Dashboard from './Dashboard';
import Comments from './Comments';

let dashboardWrapper = () => <Dashboard {...props} />,
    commentsWrapper = () => <Comments {...props} />,
    index = () => <div>
        <header>Some header</header>
        <RouteHandler />
        {this.props.children}
    </div>;

routes = {
    component: index,
    path: '/',
    childRoutes: [
      {
        path: 'comments',
        component: dashboardWrapper
      }, {
        path: 'dashboard',
        component: commentsWrapper
      }
    ]
}
于 2015-11-30T07:09:58.157 に答える
3

反応ルーター 2.x の場合。

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

そしてあなたのルートで...

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

3 番目のパラメータが次のようなオブジェクトであることを確認してください{ checked: false }

于 2016-12-14T10:04:58.567 に答える
1

React Router の問題は、コンポーネントをレンダリングするため、props を渡せなくなることです。一方、ナビゲーション ルーターでは、独自のコンポーネントをレンダリングできます。つまり、次のコードとそれに付随するJsFiddleが示すように、小道具を渡すためにフープをジャンプする必要はありません。

var Comments = ({myProp}) => <div>{myProp}</div>;

var stateNavigator = new Navigation.StateNavigator([
  {key:'comments', route:''}
]);

stateNavigator.states.comments.navigated = function(data) {
  ReactDOM.render(
    <Comments myProp="value" />,
    document.getElementById('content')
  );
}

stateNavigator.start();
于 2016-06-20T10:42:46.997 に答える
0

反応ルーター 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'})}
  )
}
...
于 2016-08-11T03:35:54.737 に答える
0

カスタム ルート コンポーネントを使用すると、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

于 2016-09-20T15:53:25.407 に答える
0

以下のようなソリューションを使用すると、v3.2.5 で機能します。

<Route
  path="/foo"
  component={() => (
    <Content
      lang="foo"
      meta={{
        description: lang_foo.description
      }}
    />
  )}
/>

また

<Route path="/foo">
  <Content
    lang="foo"
    meta={{
      description: lang_foo.description
    }}
  />
</Route>
于 2019-12-04T08:00:33.240 に答える