2016-05-13 74 views
0

我想從react.rb中使用React路由器。我開始使用反應堆路由器Gem,但Gem只能與React Router < 1一起使用,而我正在使用React Router 2.4.0,並且API非常不同。使用React路由器和React.rb

在過去的幾周裏,我採取了幾種方法來實現這一目標,但沒有一種方法是正確的,每種方法都有其缺陷。

請有人引導我在正確的方向,因爲我都沒有選擇。

在設置方面,我使用的WebPack要求做出反應並做出反應的路由器,所以這是由注射的WebPack的application.js中看起來是這樣的:

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組件,並將正確的ID傳遞給組件。

我用這種方法遇到的問題是當創建一個鏈接,因爲鏈接組件不與路由器共享相同的上下文。我相信這是由ReactDOM.render被react-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 Compo的屬性nent我看到上下文是空的,我相信這是爲什麼。 Link似乎正在被路由器背景之外的地方吸引。

方法2 - 使用反應-RB 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 - 在原生JS中構建Route組件,以便它不會被渲染:

`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 

歷史:作爲一個側面說明,無論在上面的例子,我曾試圖設置歷史例如:

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

但我得到提供折舊歷史警告,當我檢查的數值爲null。使用_reactRouter.browserHistory會超過此警告。我不確定這是否與路由器不是路由選擇這一事實有關。

我真的很感謝任何幫助或指導。甚至對於哪種方法是正確的以及如何進行的任何提示都會引起很大的興趣。

回答