3

Я создал этот образец репо, который использует рельсы (v4.2.6) с рельсами (v1.6.2) и реактивным маршрутизатором (v2.0.0-rc5): https://github.com/pioz/rails_with_react_and_react_router_exampleРезерв сервера с рельсами + реактивный рельс gem + реагирующий маршрутизатор

В файле 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> 
    ) 
    } 
} 

All работает отлично, но если я изменить вариант 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' 
... 

Как я могу вынести эту сторону сервера приложений? Правильно ли это?

ответ

1

Нашли решение: нам нужна две версии компонента 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-адреса, равной просьбой: чтобы сделать это, мы можем перейти к компоненту новой опору path с стезей запрос:

<%= react_component('MountUp', {path: request.path}, {prerender: true}) %> 
+0

В стороне сервера случае, когда страница отображается на клиенте все еще использует memoryHistory и из-за того, что если щелкнуть по ссылке URL-адрес не изменяется, но изменения содержания. Есть ли способ обойти это? –

+1

Вам необходимо использовать 2 разных компонента MountUp, один для клиентской и один на стороне сервера ... application.js, которые включают mountup_client.js e server.js, которые включают mountup_server.js – Pioz

1

Я думаю, что говорю это не пререндер не поможет

prerender: false 

Кроме того, делать, как это предлагает и захватить версию Dev так он говорит вам немного более

use the non-minified dev environment for the full error message 

Вы рассказываете он должен строить маршруты, основанные на объекте History, который должен сказать, где пользователь запросил (url). На стороне сервера вам нужно каким-то образом создать объект, который будет имитировать историю браузера с одной записью: запрошенный URL.

Я сделал это в узел с помощью Redux с помощью этого:

import createHistory from 'history/lib/createMemoryHistory'; 


var reducer = combineReducers(reducers); 

const store = compose(
    applyMiddleware(promiseMiddleware, thunk), 
    reduxReactRouter({routes, createHistory}) 
)(createStore)(reducer, {}); 

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

Лучшее сообщение об ошибке из библиотеки dev - это следующее, что вам нужно.

 Смежные вопросы

  • Нет связанных вопросов^_^