Использование React Router и React.rb

Я пытаюсь использовать React Router из реакции.rb. Я начал использовать Gem реактора-маршрутизатора, но Gem работает только с React Router < 1, ​​и я использую React Router 2.4.0, и его API совершенно другой.

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

Пожалуйста, кто-нибудь направит меня в правильном направлении, так как у меня нет выбора.

С точки зрения настройки, я использую Webpack, чтобы требовать React и React Router, поэтому application.js, который внедряется в Webpack, выглядит следующим образом:

React = require('react')
ReactDOM = require('react-dom')
_reactRouter = require('react-router')

Подход 1 - создайте Маршрутизатор как собственный JS и вызовите ReactDOM.render для рендеринга маршрутизатора при рендеринге компонента верхнего уровня

before_mount do

  @admin_members = React::API::create_native_react_class(Components::Company::AdminMember)
  @squad_index = React::API::create_native_react_class(Components::Squad::Index)
  @squad_show = React::API::create_native_react_class(Components::Squad::Show)
  @tribe_index = React::API::create_native_react_class(Components::Tribe::Index)
  @tribe_show = React::API::create_native_react_class(Components::Tribe::Show)

end

и затем рендеринг маршрутизатора в div в after_mount:

after_mount do
   `ReactDOM.render(React.createElement(
   _reactRouter.Router,
   { history: _reactRouter.browserHistory },
   React.createElement(_reactRouter.Route, { path: "admin/members", component: #{@admin_members} }),
   React.createElement(_reactRouter.Route, { path: "/squads", component: #{@squad_index} }),
   React.createElement(_reactRouter.Route, { path: "/squads/:squad_id", component: #{@squad_show} }),
   React.createElement(_reactRouter.Route, { path: "/tribes", component: #{@tribe_index} }),
   React.createElement(_reactRouter.Route, { path: "/tribes/:tribe_id", component: #{@tribe_show} })
      ), document.getElementById('bh_router_div')
   );`
end

Этот подход, хотя и не очень, кажется, работает в том, что маршрутизатор создан и функционирует, как ожидалось. URL или /tribe/22 загрузит правильный компонент TribeShow и передаст правильный идентификатор компоненту.

Проблема, с которой я сталкиваюсь при таком подходе, заключается в том, что когда дело доходит до создания ссылки, так как компонент ссылки не использует тот же контекст, что и маршрутизатор. Я полагаю, что это связано с тем, что ReactDOM.render вызывается один раз при помощи response-rb, а затем еще раз в коде выше. Это создает два корневых компонента на странице (TopLevelRailsComponent) и (ReactRouter).

Ссылка создана таким образом:

class MyRouter < React::NativeLibrary
  imports '_reactRouter'
end

И затем используется в методе рендеринга компонентов следующим образом:

MyRouter.Link({to: "/admin/members"}) { "and here is the link"}

Ссылка отображается, но нажатие на нее дает следующее предупреждение и не приводит к переходу к компоненту:

Uncaught TypeError: Cannot read property 'push' of undefined

Глядя на свойства компонента Link, я вижу, что контекст нулевой, и я считаю, что именно поэтому. Кажется, что ссылка рисуется вне контекста маршрутизатора.

Подход 2 - используйте API реагирования-рб для рендеринга маршрутизатора, чтобы ReactDOM.render не вызывался дважды на странице

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

Основываясь на том, как я создаю ссылку выше, в методе рендеринга компонента:

MyRouter.Router({history: `_reactRouter.browserHistory` },
        MyRouter.Route({ path: "/admin/members", component: @admin_members})
) {}

Но я получаю следующее предупреждение, и страница не отображается:

Uncaught Invariant Violation: <Route> elements are for router configuration only and should not be rendered

Подход 3 - создайте компонент Route в нативном JS, чтобы он не отображался:

`var AppRoutes = React.createElement(_reactRouter.Route, { path: "/admin/members", component: #{@admin_members} });`

 MyRouter.Router({history: `_reactRouter.browserHistory` },
        `AppRoutes`
 ) {}

Это проходит мимо предыдущей ошибки, НО маршрутизатор фактически не маршрутизирует, и я получаю следующее предупреждение (и компонент не рендерится):

Warning: [react-router] Location "/admin/members" did not match any routes

history: Как примечание, в обоих приведенных выше примерах я попытался установить историю как таковую:

MyRouter.Router({history: MyRouter.browserHistroy },
  `AppRoutes`
) {}

Но я получаю предупреждение о предоставлении устаревшей истории, и когда я проверяю значение, оно равно нулю. С помощью _reactRouter.browserHistoryпроходит мимо этого предупреждения. Я не уверен, имеет ли это отношение к тому факту, что маршрутизатор не маршрутизирует или нет.

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

1 ответ

Решение

Это было решено в ветке V2.4.0 реактивного маршрутизатора https://github.com/reactrb/reactrb-router/tree/v2-4-0

Также обратите внимание на новый DSL

Другие вопросы по тегам