Предполагается, что одним из самых больших преимуществ React.js является рендеринг на стороне сервера . Проблема в том, что ключевая функция React.renderComponentToString()
является синхронной, что делает невозможным загрузку каких-либо асинхронных данных, поскольку иерархия компонентов отображается на сервере.
Допустим, у меня есть универсальный компонент для комментирования, который я могу разместить где угодно на странице. У него есть только одно свойство, какой-то идентификатор (например, id статьи, под которой размещаются комментарии), а все остальное обрабатывается самим компонентом (загрузка, добавление, управление комментариями).
Мне очень нравится архитектура Flux, потому что она значительно упрощает многие вещи, а ее хранилища идеально подходят для обмена состоянием между сервером и клиентом. Как только мой магазин, содержащий комментарии, инициализирован, я могу просто сериализовать его и отправить с сервера клиенту, где его легко восстановить.
Вопрос в том, как лучше всего заполнить мой магазин. В последние дни я много гуглил и наткнулся на несколько стратегий, ни одна из которых не казалась действительно хорошей, учитывая, насколько активно эта функция React «продвигается».
На мой взгляд, самый простой способ - заполнить все мои магазины до начала фактического рендеринга. Это означает, что где-то вне иерархии компонентов (например, подключен к моему маршрутизатору). Проблема с этим подходом в том, что мне пришлось бы дважды определять структуру страницы. Рассмотрим более сложную страницу, например страницу блога с множеством различных компонентов (фактическое сообщение в блоге, комментарии, связанные сообщения, новейшие сообщения, поток Twitter ...). Мне пришлось бы спроектировать структуру страницы с использованием компонентов React, а затем где-то еще мне нужно было бы определить процесс заполнения каждого необходимого хранилища для этой текущей страницы. Мне это не кажется хорошим решением. К сожалению, большинство изоморфных туториалов разработано именно таким образом (например, этот отличный флюкс-туториал ).
React-async, . Такой подход идеален. Это позволяет мне просто определить в специальной функции в каждом компоненте, как инициализировать состояние (независимо от того, синхронно или асинхронно), и эти функции вызываются по мере того, как иерархия отображается в HTML. Он работает таким образом, что компонент не отображается до тех пор, пока состояние не будет полностью инициализировано. Проблема в том, что для этого требуются волокна который, насколько я понимаю, является расширением Node.js, изменяющим стандартное поведение JavaScript. Хотя результат мне очень нравится, мне все же кажется, что вместо того, чтобы найти решение, мы изменили правила игры. И я думаю, что нас не следует заставлять делать это, чтобы использовать эту основную функцию React.js. Я также не уверен в общей поддержке этого решения. Можно ли использовать Fiber на стандартном хостинге Node.js?
Я немного подумал сам. Я особо не продумывал детали реализации, но общая идея заключается в том, что я бы расширил компоненты аналогично React-async, а затем я бы неоднократно вызывал React.renderComponentToString () для корневого компонента. Во время каждого прохода я собирал расширяющиеся обратные вызовы, а затем вызывал их в и на проходе для заполнения магазинов. Я бы повторил этот шаг до тех пор, пока все хранилища, необходимые для текущей иерархии компонентов, не будут заполнены. Есть много вещей, которые нужно решить, и я особенно не уверен в производительности.
Я что-то пропустил? Есть другой подход / решение? Прямо сейчас я думаю о том, чтобы пойти по пути реакции-асинхронности / волокон, но я не совсем уверен в этом, как описано во втором пункте.
Связанное обсуждение на GitHub . Судя по всему, официального подхода или даже решения нет. Возможно, реальный вопрос заключается в том, как будут использоваться компоненты React. Как простой слой представления (в значительной степени мое предложение номер один) или как настоящие независимые и автономные компоненты?