Mam następującą strukturę dla mojej aplikacji React.js używającej React Router :
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);
});
Chcę przekazać niektóre właściwości do Comments
komponentu.
(normalnie zrobiłbym to tak <Comments myprop="value" />
)
Jaki jest najłatwiejszy i właściwy sposób, aby to zrobić za pomocą React Router?
javascript
properties
reactjs
react-router
Kosmetika
źródło
źródło
<ComponentA x={<ComponentB y={<ComponentC z={} />} />} />
OR<ComponentA x={ComponentB(ComponentC()) } />
W przeciwnym razie problemy z kombinacjami abstrakcji powrócą i będą wymagały mniej niż optymalnych i pośrednich rozwiązań zwanych obejściami, takimi jak zawijanie itp. Itp. Abstrakcje muszą być obywatelami pierwszej klasy jako prymitywy, niezależnie od tego, co oznacza percepcja pierwszej klasy.Odpowiedzi:
AKTUALIZACJA
Od nowej wersji możliwe jest przekazywanie rekwizytów bezpośrednio przez
Route
komponent, bez użycia Wrappera. Na przykład za pomocąrender
prop .Składnik:
Stosowanie:
Przykład Codesandbox
STARA WERSJA
Moim preferowanym sposobem jest owijanie
Comments
komponentu i przekazywanie opakowania jako procedury obsługi trasy.To jest twój przykład z zastosowanymi zmianami:
źródło
<Route path="comments" component={() => (<Comments myProp="value" />)}/>
Jeśli wolisz nie pisać opakowań, myślę, że możesz to zrobić:
źródło
route
prosty obiekt w swoim komponencie. Oto odpowiedź na problem github: github.com/rackt/react-router/issues/615#issuecomment-100432086Kopiowanie z komentarzy ciantic w przyjętej odpowiedzi:
To moim zdaniem najbardziej wdzięczne rozwiązanie. To działa. Pomogło mi.
źródło
_ref
component={(props) => (<Comments myProp="value" location={ props.location } />)}
ale znów robi się bałagancomponent={(props) => (<Comments {...props} myProp="value" />)}
utrzymywać wstrzyknięte rekwizytyJest to rozwiązanie od Rajesh , bez niewygodnego komentarza yuji , i zaktualizowane do React Router 4.
Kod wyglądałby tak:
Zauważ, że używam
render
zamiastcomponent
. Powodem jest uniknięcie niepożądanego ponownego montażu . Przekazuję równieżprops
tę metodę i używam tych samych rekwizytów w komponencie Komentarze z operatorem rozkładania obiektów (propozycja ES7).źródło
Tylko kontynuacja odpowiedzi ColCh. Wyodrębnienie opakowania komponentu jest dość łatwe:
Nie przetestowałem jeszcze tego rozwiązania, więc każda opinia jest ważna.
Należy zauważyć, że dzięki tej metodzie wszelkie rekwizyty wysyłane przez router (takie jak parametry) są nadpisywane / usuwane.
źródło
return React.createElement(Component, _.assign({}, this.props, props));
(Ten używa _.ignign do komponowania połączonego obiektu ... oczywiście dostępne są inne metody).render
,component
ichildren
metodyRoute
. Zauważ, że jak wskazuje odpowiedź @dgrcode , powinieneś użyćrender
zamiastcomponent
Możesz przekazywać rekwizyty, przekazując je do
<RouteHandler>
(w wersji 0.13.x) lub samego komponentu trasy w wersji 1.0;(z przewodnika aktualizacji na https://github.com/rackt/react-router/releases/tag/v1.0.0 )
Wszystkie osoby zajmujące się dziećmi otrzymają ten sam zestaw rekwizytów - może to być przydatne lub nie, zależnie od okoliczności.
źródło
React.cloneElement
, czy przekazano wiele elementów, ale podpis funkcji wydaje się przyjmować tylko jeden element reagujący. Myślę, że ten fragment kodu można łatwiej zrozumieć.React.cloneElement(this.props.children, {myprop: "value"})
lubReact.cloneElement(this.props.children, {myprop: this.props.myprop})
itp.Za pomocą ES6 możesz po prostu łączyć opakowania komponentów:
<Route path="/" component={() => <App myProp={someValue}/>} >
Jeśli potrzebujesz przekazać dzieci:
<Route path="/" component={(props) => <App myProp={someValue}>{props.children}</App>} >
źródło
render
zamiastcomponent
React-router v4 alpha
teraz jest na to nowy sposób, choć bardzo podobny do poprzedniej metody.
PS Działa to tylko w wersji alfa i zostały usunięte po wydaniu wersji v4 alpha. W v4 najpóźniej jest ponownie, ze ścieżką i dokładnymi rekwizytami.
reag -lego przykładowa aplikacja zawiera kod, który robi to dokładnie w route.js w swojej gałęzi React-router-4
źródło
Oto najczystsze rozwiązanie, jakie wymyśliłem (React Router v4):
MyComponent
wciąż maprops.match
iprops.location
, i maprops.foo === "lol"
.źródło
Zawiń go składnikiem funkcji bezstanowej:
źródło
Możesz także użyć mixinu RouteHandler, aby uniknąć komponentu otoki i łatwiej przekazać stan rodzica jako rekwizyty:
źródło
Możesz przekazać rekwizyty w
<RouterHandler/>
następujący sposób:Minusem tego jest to, że bezkrytycznie podajesz rekwizyty.
Comments
Może więc otrzymać rekwizyty, które naprawdę są przeznaczone dla innego komponentu, w zależności od konfiguracji tras. Nie jest to wielka sprawa, ponieważprops
jest niezmienna, ale może to być problematyczne, jeśli dwa różne komponenty oczekują rekwizytu o nazwie,foo
ale o różnych wartościach.źródło
{...props}
W wersjach 1.0 i 2.0 możesz użyć
createElement
prop,Router
aby określić, jak dokładnie utworzyć element docelowy. Źródło dokumentacjiźródło
Możesz także łączyć funkcje es6 i bezstanowe, aby uzyskać znacznie czystszy wynik:
źródło
this.props
funkcji, która na pewno nie zadziała. Jeśli używasz czystych funkcji zamiast rozszerzaćReact.Component
, musiszprops
podać jako argument, zobacz React docs on Components and PropsReact Router v 4 solution
Natknąłem się dziś na to pytanie i oto wzór, którego używam. Mamy nadzieję, że jest to przydatne dla każdego, kto szuka bardziej aktualnego rozwiązania.
Nie jestem pewien, czy jest to najlepsze rozwiązanie, ale taki jest mój obecny wzorzec. Zazwyczaj mam katalog Core, w którym przechowuję często używane komponenty wraz z ich odpowiednimi konfiguracjami (moduły ładujące, moduły itp.) I dołączam taki plik:
Następnie w danym pliku wykonaj następujące czynności:
Zauważysz, że importuję domyślny eksport mojego komponentu jako pokornego wielbłąda, co pozwala mi nazwać nowy komponent rozpoznający lokalizację w CamelCase, dzięki czemu mogę go normalnie używać. Oprócz dodatkowej linii importu i linii przypisania, komponent zachowuje się zgodnie z oczekiwaniami i odbiera wszystkie swoje rekwizyty normalnie, z dodaniem wszystkich rekwizytów trasy. W ten sposób mogę z przyjemnością przekierowywać metody cyklu życia komponentów za pomocą this.props.history.push (), sprawdzać lokalizację itp.
Mam nadzieję że to pomoże!
źródło
Dla reagowania router 2.x.
i na twoich trasach ...
upewnić 3rd param jest przedmiotem takich jak:
{ checked: false }
.źródło
Problem z React Router polega na tym, że renderuje on twoje komponenty, a więc zatrzymuje przekazywanie w rekwizytach. Router Nawigacja , z drugiej strony, pozwala na renderowanie własnych komponentów. Oznacza to, że nie musisz przeskakiwać żadnych obręczy, aby przekazać rekwizyty jako poniższy kod i towarzyszący program JsFiddle .
źródło
Użyj komponentu z routerem lub bez, w oparciu o odpowiedź Rajesh Naroth.
Lub możesz to zrobić w ten sposób:
źródło
w przypadku routera reagującego 2.5.2 rozwiązanie jest takie proste:
źródło
Przy użyciu niestandardowego komponentu trasy jest to możliwe w React Router v3.
Jeśli chodzi o
<MyRoute>
kod komponentu, powinno to być coś takiego:Aby uzyskać więcej informacji na temat niestandardowego komponentu trasy, sprawdź mój post na blogu na ten temat: http://marmelab.com/blog/2016/09/20/custom-react-router-component.html
źródło
jest to prawdopodobnie najlepszy sposób na użycie domagania-router-dom z programem obsługi plików cookie
w index.js
i użyj cookieCheck
źródło
źródło
Użyj powyższego rozwiązania, a to działa w wersji 3.2.5.
lub
źródło