denisftw
@denisftw

Как выполнить первоначальный (ре-)рендеринг в браузере React-приложения c Redux и ReactRouter?

Делаю приложение с универсальным/изоморфным рендерингом на React. Серверная часть понятна и работает: присылаем с backend'a какой-то json, синхронно помещаем его в store, а дальше ReactRouter выбирает нужный Route и рендерит правильный компонент, возвращая HTML в виде строки.

Непонятно, что делать с рендерингом в браузере.

Все компоненты требуют какие-то данные (props) чтобы отрендерится, но при этом реальные данные с сервера можно получить только асинхронно. Пока не придумал ничего умнее чем использовать onEnter в Route, но этот подход не работает:

window.onload = function() {
    const createStoreWithMiddleware = applyMiddleware(ReduxPromise)(createStore);
    const store = createStoreWithMiddleware(viewPropsReducer);
    ReactDOM.render(
        <Provider store={store} >
            <Router history={browserHistory} >
                <Route path="/" component={ViewComposite} 
                     onEnter={ ({params}) => {store.dispatch(fetchViewData()); }} />
                <Route path='/admin' component={AdminComposite} 
                     onEnter={ ({params}) => {store.dispatch(fetchAdminData()); }} />
            </Router>
        </Provider>,
        document.getElementById('viewMount')
    );
};


по причине того, что к тому моменту как promise из fetchViewData() отрезолится, рендеринг компонента уже успеет сфейлится по причине недостающих props.

В принципе, можно было бы браузерный рендеринг инициировать не в window.onload, а в then() promise'a, но тогда нужно будет дублировать логику из Router и для каждого базового компонента загружать свои данные. Или это как раз самый правильный способ?
  • Вопрос задан
  • 607 просмотров
Пригласить эксперта
Ответы на вопрос 2
Laiff
@Laiff
Front-end developer
Не самое красивое решение, но большинство реализаций универсальности работает именно так: состояние стора складывается в сериализорванном виде в глобальную переменную, и перед рендерингом из этой переменной наполняется стор и дальше растягивается по компонентам. Второй аспект это динамические данные которые нужно получить уже при рендеринге, в таком случае распространенное решение это сначала выполнить все запросы на получение таких данных на основании состояния роутера, а по резолву выполнить первоначальный рендеринг. Решение не идеальное со своими подводными камнями, но вполне работоспособное .
Ответ написан
Попробуйте https://www.npmjs.com/package/redux-async-connect

Эта либа как раз будет заботиться о загрузке данных при переходах по страницам + умеет в изоморфность.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы