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