Renderuję komponenty z mojej biblioteki wzorców zewnętrznych (node_modules). W mojej głównej aplikacji przekazuję moją Link
instancję react-router-dom
do komponentu bibliotek zewnętrznych w następujący sposób:
import { Link } from 'react-router-dom';
import { Heading } from 'my-external-library';
const articleWithLinkProps = {
url: `/article/${article.slug}`,
routerLink: Link,
};
<Heading withLinkProps={articleWithLinkProps} />
W mojej bibliotece renderuje się Link
tak:
const RouterLink = withLinkProps.routerLink;
<RouterLink
to={withLinkProps.url}
>
{props.children}
</RouterLink>
RouterLink
Wydaje się do renderowania poprawnie, a nawet przejście do adresu URL po kliknięciu.
Mój problem polega na tym, że RouterLink
wygląda na to, że odłączono się od react-router-dom
instancji mojej aplikacji . Kiedy klikam Heading
, „twardo” nawiguje, odsuwa stronę, zamiast kierować ją bezproblemowo, jak Link
zwykle.
Nie jestem pewien, co mam teraz spróbować, aby umożliwić płynną nawigację. Każda pomoc lub rada będzie mile widziana, z góry dziękuję.
Edycja: Pokazuje, jak skonfigurowany jest mój router.
import React from 'react';
import { hydrate, unmountComponentAtNode } from 'react-dom';
import { AppContainer } from 'react-hot-loader';
import { Provider } from 'react-redux';
import { createBrowserHistory } from 'history';
import { ConnectedRouter } from 'react-router-redux';
import RedBox from 'redbox-react';
import { Route } from 'react-router-dom';
import { Frontload } from 'react-frontload';
import App from './containers/App';
import configureStore from './redux/store';
import withTracker from './withTracker';
// Get initial state from server-side rendering
const initialState = window.__INITIAL_STATE__;
const history = createBrowserHistory();
const store = configureStore(history, initialState);
const mountNode = document.getElementById('react-view');
const noServerRender = window.__noServerRender__;
if (process.env.NODE_ENV !== 'production') {
console.log(`[react-frontload] server rendering configured ${noServerRender ? 'off' : 'on'}`);
}
const renderApp = () =>
hydrate(
<AppContainer errorReporter={({ error }) => <RedBox error={error} />}>
<Provider store={store}>
<Frontload noServerRender={window.__noServerRender__}>
<ConnectedRouter onUpdate={() => window.scrollTo(0, 0)} history={history}>
<Route
component={withTracker(() => (
<App noServerRender={noServerRender} />
))}
/>
</ConnectedRouter>
</Frontload>
</Provider>
</AppContainer>,
mountNode,
);
// Enable hot reload by react-hot-loader
if (module.hot) {
const reRenderApp = () => {
try {
renderApp();
} catch (error) {
hydrate(<RedBox error={error} />, mountNode);
}
};
module.hot.accept('./containers/App', () => {
setImmediate(() => {
// Preventing the hot reloading error from react-router
unmountComponentAtNode(mountNode);
reRenderApp();
});
});
}
renderApp();
źródło
<Link>
przekazać komponentu do zewnętrznej biblioteki jako argumentu lub rekwizytów? pozwoliłoby to na większą elastyczność i czysty sposób obsługi nawigacji.react-router-redux
( github.com/reactjs/react-router-redux ), chyba że masz specjalne ograniczenia wymuszające stosowanie przestarzałych wersji bibliotekreact-redux
ireact-router
bibliotek, powinieneś rozważyć przejście na nowsze wersje, ponieważ może to rozwiązać problem ). Albo zrobić upgrade, czy należy podać dokładne wersjereact
,react-router-redux
,react-redux
areact-router-dom
projekt jest obecnie za pomocą tak mamy szansę, aby znaleźć rozwiązanie łatanie.Odpowiedzi:
Zrekonstruowałem twój przypadek użycia w
codesandbox.io
i „przejście” działa dobrze. Więc może sprawdzenie mojej implementacji może ci pomóc. Jednak zamieniłem import biblioteki na import pliku, więc nie wiem, czy to decydujący czynnik, dlaczego nie działa bez przeładowania całej strony.Nawiasem mówiąc, co dokładnie rozumiesz przez „płynnie”? Czy są elementy, które pozostają na każdej stronie i nie należy ich ponownie ładować po kliknięciu linku? To tak, jak zaimplementowałem to w piaskownicy, gdzie statyczny obraz pozostaje na górze każdej strony.
Sprawdź piaskownicę .
To jest
example.js
plikA to jest
my-external-library.js
plik:źródło