web-dev-qa-db-ja.com

Reactルーターの子ルートに小道具を渡す

反応ルーターの問題を克服するのに問題があります。シナリオは、状態の親コンポーネントとルートから一連の小道具を子ルートに渡す必要があるということです。
やりたいことは、childRouteAそのpropsAを渡し、childRouteBそのpropsBを渡します。ただし、これを行う方法を理解できる唯一の方法は、RouteHandlerpropsApropsBの両方を渡すことです。つまり、関連するかどうかに関係なく、すべての子ルートがすべての子プロップを取得します。これは現時点ではブロッキングの問題ではありませんが、propAのキーがpropBのキーによってキーによって上書きされることを意味する同じコンポーネントの2つを使用する時間を見ることができます。

# routes
routes = (
  <Route name='filter' handler={ Parent } >
    <Route name='price' handler={ Child1 } />
    <Route name='time' handler={ Child2 } />
  </Route>
)

# Parent component
render: ->
  <div>
    <RouteHandler {...@allProps()} />
  </div>

timeProps: ->
  foo: 'bar'

priceProps: ->
  baz: 'qux'

# assign = require 'object-assign'
allProps: ->
  assign {}, timeProps(), priceProps()

これは実際に私が期待するように機能します。 /filters/timeにリンクすると、Child2コンポーネントがレンダリングされます。 /filters/priceにアクセスすると、Child1コンポーネントがレンダリングされます。問題は、このプロセスを実行することで、それぞれ価格と時間の小道具だけが必要な場合でも、Child1Child2の両方がallProps()に渡されることです。これらの2つのコンポーネントが同じプロップ名を持っている場合、これは問題になる可能性があり、一般に、不要なプロップでコンポーネントを膨張させるには良い方法ではありません(私の実際のケースでは2人以上の子がいるため)。
要約すると、時間ルート(filters/time)に移動するときにRouteHandler timePropsを渡し、pricePropsをRouteHandlerに渡す方法しかありません価格ルート(filters/price)に移動し、すべての小道具をすべての子ルートに渡さないようにしますか?

24
PhilVarg

同様の問題にぶつかり、ルートコンポーネントのthis.props.routeを介してRouteに設定されている小道具にアクセスできることを発見しました。これを知って、次のようにコンポーネントを整理しました。

index.js

React.render((
  <Router history={new HashHistory()}>
    <Route component={App}>
        <Route
          path="/hello"
          name="hello"
          component={views.HelloView}
          fruits={['orange', 'banana', 'grape']}
        />
    </Route>
  </Router>
), document.getElementById('app'));

App.js

class App extends React.Component {
  constructor(props) {
    super(props);
  }

  render() {
    return <div>{this.props.children}</div>;
  }
}

HelloView.js

class HelloView extends React.Component {
  constructor(props) {
    super(props);
  }

  render() {
    return <div>
      <ul>
        {this.props.route.fruits.map(fruit => 
          <li key={fruit}>{fruit}</li>
        )}
      </ul>
    </div>;
  }
}

これは、react-router v1.0-beta3を使用しています。お役に立てれば!


さて、あなたの問題をよりよく理解できたので、試してみてください。

子の小道具は単一の親から来るため、どの小道具を渡すかを制御できるように、react-routerではなく、親コンポーネントがどの子をレンダリングするかを管理する必要があります。

Paramを使用するようにルートを変更してから、親コンポーネントでそのparamを調べて、適切な子コンポーネントをレンダリングできます。

ルート

<Route name="filter" path="filter/:name" handler={Parent} />

親コンポーネント

render: function () {
  if (this.props.params.name === 'price') {
    return <Child1 {...this.getPriceProps()} />
  } else if (this.props.params.name === 'time') {
    return <Child2 {...this.getTimeProps()} />
  } else {
    // something else
  }
}
29
Jim Skerritt

子コンポーネントでは、

return <div>{this.props.children}</div>

プロップを親とマージできます

var childrenWithProps = React.cloneElement(this.props.children, this.props);
return <div>{childrenWithProps}</div>
11
Alex Shwarc

React.cloneElementを使用して子コンポーネントをレンダリングし、ルートで定義されている子ルートコンポーネント内で利用可能なデータを渡すことができます。

たとえば、ここではuserの値をreact childRouteコンポーネントに渡します。

{React.cloneElement(this.props.childRoute, { user: this.props.user })}
0
Paritosh Pundir