Pasar el enlace de react-router-dom a una biblioteca externa

10

Estoy renderizando componentes desde mi biblioteca de patrones externos (node_modules). En mi aplicación principal, paso mi Linkinstancia react-router-domal componente de mis bibliotecas externas de la siguiente manera:

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

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

<Heading withLinkProps={articleWithLinkProps} />

En mi biblioteca, está renderizando Linkasí:

const RouterLink = withLinkProps.routerLink;

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

El RouterLinkparece representar correctamente, e incluso navega a la dirección URL cuando se hace clic.


Mi problema es que RouterLinkparece haberse separado de la react-router-dominstancia de mi aplicación . Cuando hago clic Heading, se navega "con fuerza", publicando de nuevo la página en lugar de enrutarla sin problemas como lo Linkharía normalmente.

No estoy seguro de qué probar en este momento para permitirle navegar sin problemas. Cualquier ayuda o consejo sería apreciado, gracias de antemano.

Editar: muestra cómo está configurado mi enrutador.

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
fuente
¿Por qué no hacer que tu <Link>componente pase a tu biblioteca externa como argumento o accesorios? eso permitiría una mayor flexibilidad y su forma limpia de manejar la navegación.
RAÍZ
¿Puedes mostrar cómo configuras tu enrutador? ¿Es un navegador, memoria o enrutador estático?
zero298
@ zero298 - Pregunta actualizada
danjones_mcr
@mamounothman: así es como se está haciendo actualmente, pero parece afectar la forma en que navega hacia una devolución de datos.
danjones_mcr
Está utilizando la biblioteca en desuso react-router-redux( github.com/reactjs/react-router-redux ), a menos que tenga una restricción especial para imponer el uso de versiones obsoletas de las bibliotecas react-reduxy react-router, debería considerar la posibilidad de pasar a versiones más nuevas, ya que puede solucionar su problema ) O haces la actualización, o que debe ofrecer las versiones exactas de react, react-router-redux, react-reduxy react-router-domsu proyecto utiliza actualmente por lo que tenemos la oportunidad de encontrar una solución de parcheo.
GonArrivi

Respuestas:

2

He reconstruido su caso de uso codesandbox.ioy la "transición" funciona bien. Entonces, tal vez revisar mi implementación podría ayudarlo. Sin embargo, reemplacé la importación de la biblioteca por una importación de archivos, por lo que no sé si ese es el factor decisivo de por qué no funciona sin una recarga completa de la página.

Por cierto, ¿qué quieres decir exactamente con "sin problemas"? ¿Hay elementos que permanecen en cada página y no deberían volver a cargarse al hacer clic en el enlace? Esto es como lo implementé en el sandbox donde una imagen estática permanece en la parte superior de cada página.


Echa un vistazo a la caja de arena .

Este es el example.jsarchivo

// 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>
);

Y este es el my-external-library.jsarchivo:

import React from "react";

export const Heading = ({ withLinkProps }) => {
  const RouterLink = withLinkProps.routerLink;
  return <RouterLink to={withLinkProps.url}>Superlink</RouterLink>;
};
New3D
fuente
Hola, muchas gracias por la respuesta! Parece que solo al pasar a través de node_modules, se produce el problema.
danjones_mcr