Ответ 1
Извлечение внутри компонента с помощью componentWillMount
не является подходящим местом, если вам необходимо отобразить серверную часть. Вам нужно как-то переместить его из компонента формы и передать фактические данные в качестве реквизита после его получения - например, как @JakeSendar, предложенный в его ответе.
У меня есть опыт работы с изоморфным приложением с React, и главная проблема, с которой я столкнулся, - это подождать, пока все данные будут загружены до первого рендеринга
Как уже упоминалось в комментариях @FakeRainBrigand, есть только один способ сделать это, и это зависит от ваших требований.
Существует несколько способов создания изоморфного приложения, интересное с моей точки зрения: https://github.com/webpack/react-starter и http://fluxible.io/
Но самый элегантный способ сделать это, как я понял для себя, - организовать асинхронный рендеринг для реагирующих компонентов, в частности, с помощью RxJS.
В целом мое приложение структурировано следующим образом:
- views - Реагировать на компоненты без какой-либо логики (просто представление)
-
- Наблюдаемые с текущим состоянием (исходные данные загружаются с использованием суперагента, затем объединены с другими моделями и/или результатами действий). В простом случае это что-то вроде:
Rx.Observable.defer(fetchData).concat(updatesSubject).shareReplay()
-
действия (или намерения) - наблюдатели, используемые для сбора пользовательского ввода, выполнения чего-либо и отправки результатов действий для моделей подписчиков и/или других действий. В простом случае что-то вроде:
updatesSubject = new Rx.Subject();
action = new Rx.Subject();
action.switchMap(asyncRequest).subscribe(updatesSubject)
-
Компоненты - Observables (поток виртуальных элементов DOM), объединенный с моделями, другими компонентами и действиями (У меня есть примечание об этом, объясняя, как и зачем создавать элементы Observerable React с RxJS), теперь я планирую добавлять частичные компоненты (кортеж из: компонент реакции, наблюдаемые, наблюдатели и свойства, частично заполненные с использованием DI)
-
router - компонент, ответственный за обработку изменений местоположения, в основном основная особенность заключается в отображении изменений местоположения в поток виртуальных элементов DOM и метаинформации. Но в деталях, это немного сложнее в моем случае (генерация URL-адресов, активное выделение URL-адресов, обработка прокрутки при навигации, а также возможность вложенных маршрутов и несколько просмотров).
Все это собрано вместе с использованием контейнера DI, в моем случае, аналогичном angular2 контейнеру DI, но значительно упрощенному для моих конкретных потребностей.
Компоненты, модели и действия создаются с использованием DI.
На стороне сервера приложение выглядит следующим образом:
var rootInjector = new Injector();
// setup server specific providers
rootInjector.provide(..., ...)
app.get('/*', function(req,res){
var injector = rootInjector.createChild();
// setup request specific providers
injector.provide(..., ...);
injector.get(Router)
.first()
.subscribe(function(routingResult){
res.render('app', {
title: routingResult.title,
content: React.renderToString(routingResult.content)
});
});
}
и аналогичные на стороне клиента:
var rootInjector = new Injector();
// setup server specific providers
// actually this is omitted in my case because default providers are client side
rootInjector.provide(..., ...)
contentElement = document.getElementById('#content');
rootInjector.get(Router)
.subscribe(function(routingResult){
document.title = routingResult.title;
React.render(routingResult.content, contentElement)
});
По сравнению с потоком, это более декларативный и более мощный способ организовать приложение. И в случае изоморфного приложения - для меня это выглядит намного лучше, чем различные хаки с флюсом. Но, конечно, есть недостатки... - это сложнее.
Скорее позже, я открою все это, но пока - он не совсем готов к публикации.
UPD1:
Оригинальный ответ немного устарел (позже я планирую его обновить), и у меня есть некоторый прогресс в этой области.
Ссылки на код, упомянутый выше, уже раскрыты:
- контейнер DI: di1
- Контейнер для реагирования компонентов (соединение с наблюдаемыми и общими): rx-react-container
- Стартовый шаблон для реализации изоморфных виджетов с использованием RxJS и React и выше: Реактивные виджеты
О полном приложении (работа продолжается и документация там не очень хорошая, но в целом это должно быть понятно):
- Маршрутизатор, созданный специально для изоморфных реактивных приложений router1 и реагирует на его компоненты router1-react
- Шаблон приложения с маршрутизатором и всеми упомянутыми выше библиотеками: router1-app-template