Передача посилання реакції-маршрутизатора-dom у зовнішню бібліотеку


10

Я передаю компоненти з моєї зовнішньої бібліотеки шаблонів (node_modules). У своєму головному додатку я передаю свій Linkекземпляр із react-router-domкомпонента в мої зовнішні бібліотеки так:

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

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

<Heading withLinkProps={articleWithLinkProps} />

У моїй бібліотеці він відображає Linkтак:

const RouterLink = withLinkProps.routerLink;

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

RouterLink, Здається, правильно роблять, і навіть переходить до URL при натисканні.


Моя проблема полягає в тому, що, RouterLinkсхоже, відійшов від react-router-domекземпляра мого додатка . Коли я натискаю Heading, він "важко" пересувається, оновлює сторінку, а не прямує туди, як Linkзазвичай.

Я не впевнений, що спробувати в цей момент, щоб дозволити йому безперешкодно переміщатися. Будь-яка допомога чи порада буде вдячна, заздалегідь дякую.

Редагувати: показує, як настроюється мій маршрутизатор.

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

Чому б ваш <Link>компонент не перейшов до зовнішньої конвертації як аргумент чи реквізит? це дозволило б отримати більшу гнучкість та чистий спосіб керування навігацією.
Ma'moun осман

Чи можете ви показати, як налаштувати свій маршрутизатор? Це браузер, пам'ять чи статичний маршрутизатор?
нуль298

@ zero298 - Оновлено запитання
danjones_mcr

@mamounothman - Ось так це робиться в даний час, але, здається, це впливає на те, як він переходить на пост-назад.
danjones_mcr

Ви використовуєте застарілу бібліотеку react-router-redux( github.com/reactjs/react-router-redux ), якщо у вас немає спеціального обмеження для застосування застарілих версій react-reduxі react-routerбібліотек, вам слід розглянути можливість переходу до новіших версій, оскільки це може вирішити вашу проблему. ). Або ви робите оновлення, або ви повинні надати точні варіанти react, react-router-redux, react-reduxі react-router-domваш проект в даний час використовує тому у нас є шанс знайти рішення внесення виправлень.
GonArrivi

Відповіді:


2

Я реконструював ваш випадок використання в, codesandbox.ioі "перехід" працює чудово. Тож можливо перевірка моєї реалізації може вам допомогти. Однак я замінив імпорт бібліотеки на імпорт файлу, тому не знаю, чи це вирішальний фактор, чому він не працює без перезавантаження цілої сторінки.

До речі, що ви маєте на увазі саме під «безшовно»? Чи є елементи, які залишаються на кожній сторінці і їх не слід перезавантажувати знову при натисканні на посилання? Це так, як я реалізував це в пісочниці, де статична картинка залишається вгорі на кожній сторінці.


Ознайомтеся з пісочницею .

Це example.jsфайл

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

І ось my-external-library.jsфайл:

import React from "react";

export const Heading = ({ withLinkProps }) => {
  const RouterLink = withLinkProps.routerLink;
  return <RouterLink to={withLinkProps.url}>Superlink</RouterLink>;
};

Привіт, велике спасибі за відповідь! Схоже, що лише при переході через node_modules виникає проблема.
danjones_mcr
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.