Übergabe des Links von react-router-dom an eine externe Bibliothek

10

Ich rendere Komponenten aus meiner externen Musterbibliothek (node_modules). In meiner Haupt-App übergebe ich meine LinkInstanz react-router-domwie folgt an die Komponente meiner externen Bibliotheken:

import { Link } from 'react-router-dom';
import { Heading } from 'my-external-library';

const articleWithLinkProps = {
    url: `/article/${article.slug}`,
    routerLink: Link,
  };

<Heading withLinkProps={articleWithLinkProps} />

In meiner Bibliothek wird Folgendes gerendert Link:

const RouterLink = withLinkProps.routerLink;

<RouterLink
  to={withLinkProps.url}
>
  {props.children}
</RouterLink>

Das RouterLinkscheint korrekt zu rendern und navigiert beim Klicken sogar zur URL.


Mein Problem ist, dass sich das RouterLinkanscheinend von der react-router-domInstanz meiner App gelöst hat . Wenn ich auf klicke Heading, ist es "schwer" zu navigieren und die Seite zurückzusenden, anstatt wie gewohnt nahtlos dorthin Linkzu gelangen.

Ich bin mir nicht sicher, was ich an dieser Stelle versuchen soll, damit es nahtlos navigieren kann. Jede Hilfe oder Beratung wäre dankbar, danke im Voraus.

Bearbeiten: Zeigt an, wie mein Router eingerichtet ist.

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();
danjones_mcr
quelle
Warum nicht Ihre <Link>Komponente als Argument oder Requisit an Ihre externe Bibliothek weitergeben lassen? Dies würde mehr Flexibilität und eine saubere Handhabung der Navigation ermöglichen.
Ma'moun othman
Können Sie zeigen, wie Sie Ihren Router eingerichtet haben? Ist es ein Browser, ein Speicher oder ein statischer Router?
Null298
@ zero298 - Aktualisierte Frage
danjones_mcr
@mamounothman - So wird es derzeit gemacht, scheint aber die Art und Weise zu beeinflussen, wie es zu einem Post-Back navigiert.
danjones_mcr
Wenn Sie die veraltete Bibliothek react-router-redux( github.com/reactjs/react-router-redux ) verwenden, sollten Sie in Betracht ziehen, auf neuere Versionen zu wechseln , es sei denn, Sie haben eine besondere Einschränkung bei der Durchsetzung der Verwendung veralteter Versionen von react-reduxund react-routerBibliotheken, da dies Ihr Problem beheben kann ). Entweder führen Sie das Upgrade durch, oder Sie sollten die genauen Versionen von reactangeben react-router-redux, react-reduxund react-router-domIhr Projekt wird derzeit verwendet, damit wir die Möglichkeit haben, eine Patch-Lösung zu finden.
GonArrivi

Antworten:

2

Ich habe Ihren Anwendungsfall in rekonstruiert codesandbox.iound der "Übergang" funktioniert einwandfrei. Vielleicht hilft Ihnen das Auschecken meiner Implementierung. Ich habe den Bibliotheksimport jedoch durch einen Dateiimport ersetzt, sodass ich nicht weiß, ob dies der entscheidende Faktor dafür ist, warum er ohne ein erneutes Laden der gesamten Seite nicht funktioniert.

Was meinst du übrigens genau mit "nahtlos"? Gibt es Elemente, die auf jeder Seite verbleiben und beim Klicken auf den Link nicht erneut geladen werden sollten? Dies ist so, als hätte ich es in der Sandbox implementiert, in der auf jeder Seite ein statisches Bild oben bleibt.


Schauen Sie sich den Sandkasten an .

Dies ist die example.jsDatei

// This sandbox is realted to this post https://stackoverflow.com/q/59630138/965548

import React from "react";
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
import { Heading } from "./my-external-library.js";

export default function App() {
  return (
    <div>
      <img
        alt="flower from shutterstock"
        src="https://image.shutterstock.com/image-photo/pink-flowers-blossom-on-blue-600w-1439541782.jpg"
      />
      <Router>
        <Route exact={true} path="/" render={Welcome} />
        <Route path="/article/coolArticle" component={CoolArticleComponent} />
      </Router>
    </div>
  );
}

const Welcome = () => {
  const articleWithLinkProps = {
    url: `/article/coolArticle`,
    routerLink: Link
  };

  return (
    <div>
      <h1>This is a super fancy homepage ;)</h1>
      <Heading withLinkProps={articleWithLinkProps} />
    </div>
  );
};

const CoolArticleComponent = () => (
  <div>
    <p>This is a handcrafted article component.</p>
    <Link to="/">Back</Link>
  </div>
);

Und das ist die my-external-library.jsDatei:

import React from "react";

export const Heading = ({ withLinkProps }) => {
  const RouterLink = withLinkProps.routerLink;
  return <RouterLink to={withLinkProps.url}>Superlink</RouterLink>;
};
New3D
quelle
Hallo, vielen Dank für die Antwort! Es scheint, als ob das Problem nur beim Übergeben über node_modules auftritt.
danjones_mcr