web-dev-qa-db-fra.com

Passer des accessoires à React Router children routes

J'ai du mal à surmonter un problème avec le routeur React. Le scénario est que j'ai besoin de transmettre aux enfants des routes un ensemble d'accessoires à partir d'un composant parent d'état et d'une route.
ce que je voudrais faire, c'est passer childRouteA son propsA, et passer childRouteB son propsB. Cependant, la seule façon dont je peux comprendre comment faire est de passer RouteHandler à la fois propsA et propsB ce qui signifie que chaque route enfant obtient chaque accessoire enfant, que ce soit pertinent ou non . ce n'est pas un problème de blocage pour le moment, mais je peux voir un moment où j'utiliserais les deux du même composant, ce qui signifie que les clés sur propA seront écrasées par les clés par les clés de propB.

# 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()

Cela fonctionne réellement comme je m'y attendais. Lorsque je crée un lien vers /filters/time, Le composant Child2 Est rendu. quand je vais dans /filters/price j'obtiens le composant Child1. le problème est qu'en faisant ce processus, Child1 et Child2 sont tous deux passés allProps() même s'ils n'ont besoin que d'accessoires de prix et de temps, respectivement. Cela peut devenir un problème si ces deux composants ont un nom d'accessoire identique et en général ce n'est tout simplement pas une bonne pratique de gonfler les composants avec des accessoires inutiles (car il y a plus de 2 enfants dans mon cas réel).
donc en résumé, y a-t-il un moyen de passer les RouteHandler timeProps quand je vais sur la route du temps (filters/time) et de ne passer que priceProps RouteHandler quand je vais sur la route des prix (filters/price) et évite de passer tous les accessoires à toutes les routes enfants?

24
PhilVarg

J'ai rencontré un problème similaire et j'ai découvert que vous pouvez accéder aux accessoires définis sur Route à this.props.route dans votre composant d'itinéraire. Sachant cela, j'ai organisé mes composants comme ceci:

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

Ceci utilise react-router v1.0-beta3. J'espère que cela t'aides!


Ok, maintenant que je comprends mieux votre problème, voici ce que vous pouvez essayer.

Étant donné que vos accessoires enfants proviennent d'un seul parent, votre composant parent, et non react-router, devrait être celui qui gère quel enfant est rendu afin que vous puissiez contrôler quels accessoires sont passés.

Vous pouvez essayer de modifier votre itinéraire pour utiliser un paramètre, puis inspecter ce paramètre dans votre composant parent pour rendre le composant enfant approprié.

Route

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

Composant 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

Dans le composant enfant, au lieu de

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

Vous pouvez fusionner les accessoires avec le parent

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

React.cloneElement peut être utilisé pour rendre le composant enfant et ainsi transmettre toutes les données disponibles à l'intérieur du composant de route enfant défini dans la route.

Par exemple, ici je passe la valeur de user au composant react childRoute.

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