我创建了这个使用rails(v4.2.6)和react-rails(v1.6.2)以及react-router(v2.0.0-rc5)的示例repo:https://github.com/pioz/rails_with_react_and_react_router_example
在文件app/views/application/react_entry_point.html.erb
中,我使用
MountUp
<%= react_component('MountUp', {}, {prerender: false}) %>
组件MountUp
呈现我的路由器:
class MountUp extends React.Component {
render() {
return(
<Router history={History}>
<Route path="/" component={App}>
<IndexRoute component={Index} />
<Route path="/contact" component={Contact}/>
<Route path="/about" component={About}/>
</Route>
</Router>
)
}
}
一切正常,但如果我更改选项prerender: true
,我会收到一个奇怪的错误React::ServerRendering::PrerenderError in Application#react_entry_point
:
Encountered error "Error: Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings." when prerendering MountUp with {}
Object.invariant [as default] ((execjs):21983:16)
createHashHistory ((execjs):24108:130)
(execjs):22633:20
wrapDeprecatedHistory ((execjs):25285:61)
createRouterObjects ((execjs):25259:23)
componentWillMount ((execjs):25228:38)
ReactCompositeComponentMixin.mountComponent ((execjs):8138:13)
wrapper [as mountComponent] ((execjs):3131:22)
Object.ReactReconciler.mountComponent ((execjs):6583:36)
ReactCompositeComponentMixin.mountComponent ((execjs):8153:35)
/Users/pioz/.rvm/gems/ruby-2.3.0/gems/execjs-2.6.0/lib/execjs/external_runtime.rb:39:in `exec'
...
如何呈现此应用服务器端?这是正确的方法吗?
答案 0 :(得分:2)
找到解决方案:我们需要两个版本的组件MountUp
:使用浏览器历史记录的客户端版本和使用虚假内存历史记录的服务器版本。这里是组件的两个版本:
// client version
class MountUp extends React.Component {
render() {
return(
<Router history={History}>
<Route path="/" component={App}>
<IndexRoute component={Index} />
<Route path="/contact" component={Contact}/>
<Route path="/about" component={About}/>
</Route>
</Router>
)
}
}
// server version
class MountUp extends React.Component {
render() {
return(
<Router history={createMemoryHistory(this.props.path)}>
<Route path="/" component={App}>
<IndexRoute component={Index} />
<Route path="/contact" component={Contact}/>
<Route path="/about" component={About}/>
</Route>
</Router>
)
}
}
我们还需要使用等于请求的url路径创建内存历史记录:要执行此操作,我们可以使用请求的路径将新的prop path
传递给组件:
<%= react_component('MountUp', {path: request.path}, {prerender: true}) %>
答案 1 :(得分:1)
我认为告诉它不要放弃不会帮助
prerender: false
另外,按照它建议并抓住开发版本,它会告诉你更多
use the non-minified dev environment for the full error message
您告诉它基于History
对象构建路由,该对象应该说明用户请求的位置(网址)。在服务器端,您需要以某种方式构造一个对象,该对象将使用一个条目模拟浏览器历史记录:请求的URL。
我在使用Redux的节点中完成了这个:
import createHistory from 'history/lib/createMemoryHistory';
var reducer = combineReducers(reducers);
const store = compose(
applyMiddleware(promiseMiddleware, thunk),
reduxReactRouter({routes, createHistory})
)(createStore)(reducer, {});
但是您需要采用不同的方法才能将Rails request
详细信息放入历史存储中。
您需要从dev库获得更好的错误消息。