Переход от реагирующего маршрутизатора 3.x к 4.x

Как перейти к использованию https://cdnjs.cloudflare.com/ajax/libs/react-router/4.0.0-2/react-router.min.js с помощью https://cdnjs.cloudflare.com/ajax/libs/react-router/3.0.1/ReactRouter.min.js?

Пример использования 3.x ниже.

HTML

<script src="https://unpkg.com/[email protected]/dist/react.min.js"></script>
<script src="https://unpkg.com/[email protected]/dist/react-dom.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-router/3.0.1/ReactRouter.min.js"></script>

JS

let { Router, IndexRoute, Redirect, Route, Link, browserHistory } = ReactRouter;

history.replaceState(0,0,'/');

const Main = () =>
  <Router history={browserHistory}>

    <Route path='/' component={App}>
      <IndexRoute component={Home}/>
      <Route path='map' component={Map}/>
      <Route path='settings' component={Settings}/>
            <Redirect from='foo' to='/' />
      <Route path='*' component={NotFound}/>
    </Route>

  </Router>

const App = props => 
  <div>
    <Navigation>
      <Link to='/map'>Map</Link>
      <Link to='/settings'>Settings</Link>
      <Link to='/foo'>Foo</Link>
    </Navigation>

    {props.children}

  </div>

const Navigation = props => <nav {...props} />
const Home = () => <h1>Home</h1>
const Map = () => <h1>Map</h1>
const Settings = () => <h1>Settings</h1>
const NotFound = (props) => <h1>404 - Not Found</h1>

ReactDOM.render(<Main />, document.body);

Посмотрите на действие: https://jsfiddle.net/developit/nvpr63eg/

Если я перейду на любую версию CDX с 4-мя версиями, хотя она не работает (код недоступен после команды возврата).

Ответ 1

Я смог настроить его с помощью сокращения, изменив несколько вещей:

Во-первых, browserHistory больше не определяется на react-router. Один из способов вернуть его - использовать пакет history.

Вам нужно будет установить (необязательный вариант redux):

npm i -S history react-router react-router-redux

Вместо попытки импортировать browserHistory используйте:

import { createBrowserHistory } from 'history';

Если вы хотите использовать redux, тогда импортируйте это и добавьте его в свои комбинированные редукторы:

import { routerReducer as routing } from 'react-router-redux';

combineReducers({
  home, about,
  routing, // new
});

Затем вы создаете объект history

// redux
import { syncHistoryWithStore } from 'react-router-redux';
const history = syncHistoryWithStore(createBrowserHistory(), store);

// regular
const history = createBrowserHistory();

Затем измените свой маршрутизатор на использование нового объекта history

<Router history={ history } children={ Routes } />

Все остальное должно быть одинаковым.


Если кто-то сталкивается с The prop history is marked as required in Router, but its value is undefined.

Это связано с тем, что browserHistory больше не доступен в agent-маршрутизаторе, см. сообщение, чтобы использовать пакет истории.


Связанные

Ответ 2

Это дополнительный ответ на один Павел S, опубликованный выше. Кредит должен по-прежнему переходить на его публикацию.

Причина m дополнения ответа bcoz: -

  • У меня возникли ошибки с BrowserHistory и Link.
  • Мне пришлось включить response-router-dom.
  • была опечаткой (в оригинальном ответе Паулса)

шаг нити:

yarn add react-router
yarn add react-router-dom

package.json:

 "react": "^15.6.1",
    "react-dom": "^15.6.1",
    "react-router": "^4.1.1",
    "react-router-dom": "^4.1.1"

index.js:

import React from 'react';
import ReactDOM from 'react-dom';
import { Switch, Redirect, Route} from 'react-router';
import {BrowserRouter, Link} from 'react-router-dom';


//let { BrowserRouter, Switch, Redirect, Route, Link } = ReactRouter;

const Main = () =>
  <BrowserRouter>
    <App>
      <Switch>
        <Route exact path='/' component={Home}/>
        <Route path='/map' component={Map}/>
        <Route path='/settings' component={Settings}/>
        <Route path='/foo' component={Foo}/>
        <Route component={NotFound}/>
      </Switch>
    </App>
  </BrowserRouter>

const App = props =>
  <div>
    <Navigation>
      <Link to='/map'>Map</Link>
      <Link to='/settings'>Settings</Link>
      <Link to='/foo'>Foo</Link>
    </Navigation>

    {props.children}

  </div>

const Navigation = props => <nav {...props} />
const Home = () => <h1>Home</h1>
const Map = () => <h1>Map</h1>
const Settings = () => <h1>Settings</h1>
const Foo = () => <Redirect to='/' />
const NotFound = (props) => <h1>404 - Not Found</h1>

ReactDOM.render(<Main />, document.body);

введите описание изображения здесь

Ответ 3

Там должно быть руководство по обновлению ближе к полной версии. Я адаптировал ваш код для предстоящей беты вместо текущей альфы. Бета-версия еще не выпущена, поэтому, к сожалению, нет размещенной версии React Router, с которой вы сможете проверить это.

let { BrowserRouter, Switch, Redirect, Route, Link } = ReactRouter;

const Main = () =>
  <BrowserRouter>
    <App>
      <Switch>
        <Route exact path='/' component={Home}/>
        <Route path='/map' component={Map}/>
        <Route path='/settings' component={Settings}/>
        <Route path='/foo' component={Foo}/>
        <Route component={NotFound}/>
      </Switch>
    </App>
  </BrowserRouter>

const App = props => 
  <div>
    <Navigation>
      <Link to='/map'>Map</Link>
      <Link to='/settings'>Settings</Link>
      <Link to='/foo'>Foo</Link>
    </Navigation>

    {props.children}

  </div>

const Navigation = props => <nav {...props} />
const Home = () => <h1>Home</h1>
const Map = () => <h1>Map</h1>
const Settings = () => <h1>Settings</h1>
const Foo = () => <Redirect to='/' />
const NotFound = (props) => <h1>404 - Not Found</h1>

ReactDOM.render(<Main />, document.body);

Ответ 4

Конечно, вы можете, но вам нужно будет переписать некоторые из ваших компонентов и логики приложений, потому что ваш код не будет работать, как сейчас.

Прочитайте официальную документацию, здесь. Там также есть хороший FAQ об этих изменениях, здесь. Вот выдержка:

Почему огромное изменение?

tl; dr Декларативная составность.

Мы никогда не были в восторге от React Router. Как и вы, мы много узнали о Реате, так как мы его сначала подняли. Мы построили Router лучшее, что мы знали по пути. То, что мы узнали больше всего, это то, что мы любим React из-за его декларативной композиции.

Если вы хотите обновить, скоро появится руководство по обновлению, согласно официальному источнику:

Мы очень сильно верим в итеративную миграцию, а не переписываем приложения. Мы работаем над руководством по переносу, но основная стратегия заключается в том, что обе версии будут запускаться в тандеме (из-за ограничений на npm, мы опубликуем предыдущую версию отдельно, чтобы оба они могли быть установлены).

Вы сможете маршрутизировать один за другим и перенести их в новый API. Кроме того, упомянутый выше аддон конфигурации может помочь здесь.


С учетом этого, возвращаясь к исходной проблеме: чтобы ваш компонент App работал правильно, теперь он должен выглядеть примерно так:

const App = props => 
  <div>
    <Navigation>
      <Link to='/map'>Map</Link>
      <Link to='/settings'>Settings</Link>
      <Link to='/foo'>Foo</Link>
    </Navigation>
    {props.children}
  </div>

  <Match exactly pattern="/" component={Home} />
  <Match pattern="/map" component={Map} />
  <Match pattern="/settings" component={Settings} />
  <Match pattern="/topics" component={Topics} />

                         

Надеюсь, это поможет. Удачи.


edit. По-видимому @PaulS имеет пример для будущей версии React-Router v4. Если сообщение является точным, вышеуказанный код не будет работать в будущем; он будет работать только для текущей версии. Следите за ссылками на связанные страницы, чтобы узнать, когда RRv4 выйдет в эфир.

Ответ 5

Есть несколько вещей, которые следует отметить с недавним выпуском v4, касающимся вашего jsfiddle. Прежде всего, что библиотека в целом разделена: веб, родной и основной (используйте в любом месте). Используйте функцию-router-dom только для Интернета.

2: То, как вы устанавливаете маршруты, совсем другое. Вместо того, чтобы вложенные маршруты в ваш родительский компонент, который вы фактически не можете сделать, все, что вам нужно сделать, это определить ваш родительский компонент (BrowserRouter в этом случае), а затем вы можете определять маршруты по всем вашим компонентам. Теперь ваши компоненты определяют иерархию. Например, вы можете организовать компоненты Main и App следующим образом:

const Main = () => (
  <BrowserRouter>
    <App />
  </BrowserRouter>
)

const App = props => (
  <div>
    <Navigation>
      <Link to='/'>Home</Link>
      <Link to='/map'>Map</Link>
      <Link to='/settings'>Settings</Link>
      <Link to='/foo'>Foo</Link>
    </Navigation>

    <Route exact path='/' component={Home}/>
    <Route path='/map' component={Map}/>
    <Route path='/settings' component={Settings}/>
    <Route path='/foo' render={() => (
        <Redirect to="/"/>
    )}/>
  </div>
)

Надеюсь, это поможет. Пожалуйста, взгляните на мое исправление для вашего jsfiddle ниже, и дайте мне знать, если у вас есть какие-либо вопросы.

https://jsfiddle.net/bagofcole/kL6m8pjk/12/

За дополнительной информацией обращайтесь: https://reacttraining.com/react-router/web/guides/quick-start