Внутри каждого компонента вы должны определить функцию, назовем ее loadData. эта функция будет выполнять асин c работу вашего компонента. когда ваш сервер получает запрос, вы должны посмотреть этот URL, а затем решить, какие компоненты отображать.
Для каждого компонента, который необходимо отобразить, мы будем вызывать функцию loadData, которая прикреплена к каждому из компонентов, чтобы инициировать процесс загрузки данных. Ключевым моментом здесь является то, что мы не делаем начальный рендеринг приложения. У нас просто есть набор компонентов. Каждый говорит: «Вот ресурс, который мне нужен». Затем всякий раз, когда кто-то делает запрос, мы смотрим на набор компонентов, которые нам нужно визуализировать, чтобы показать страницу. Затем мы возьмем все эти компоненты, возьмем эти маленькие функции требований к загрузке данных, которые прикреплены к ним, и мы вызовем каждый из них. Все эти функции dataLoad возвращают обещание, поэтому мы должны обнаружить, что все они решены, прежде чем мы представим наше приложение. Допустим, у нас есть Users. js, поэтому мы определяем нашу функцию следующим образом:
const loadData = store => {
return store.dispatch(fetchUsers());
};
, когда мы импортируем наш компонент, мы импортируем внутри объекта.
export default {
loadData:loadData,
component: connect(mapStateToProps, { fetchUsers })(UsersList)
};
Мы должны настроить наши маршруты. js файл с помощью реагирующий маршрутизатор-config .
Маршруты. js
import React from "react";
import Home from "./pages/Home";
import Users from "./pages/UsersList";
import App from "./App";
import NotFoundPage from "./pages/NotFoundPage";
export default [
{
...App,
//App component will be shown inside each component.
//array of routes will be used inside the App.js down below
routes: [
{
path: "/",
...Home,
exact: true
},
{ ...UsersList, path: "/users" },
{ ...AdminsListPage, path: "/admins" },
{ ...NotFoundPage }
]
}
];
Вот приложение. js
import React from "react";
import Header from "./components/Header";
import { renderRoutes } from "react-router-config";
import { fetchCurrentUser } from "./actions";
//this component is to render components that each component uses in common
//props.route is the child components that are passed from Routes.js
const App = ({ route }) => {
return (
<div>
<Header />
{renderRoutes(route.routes)}
</div>
);
};
export default {
component: App,
//this function is get called by redux so store is passed in
//as you might know Header should always know about authentication status
//we populate the store with the authentication info so Header can use it.
loadData: ({ dispatch }) => dispatch(fetchCurrentUser())
};
Теперь мы настроили все функции loadData, теперь пришло время чтобы вызвать их, когда наш сервер получает запрос. для этого мы будем использовать функцию matchRoutes
из response-router-config.
app.get("*", (req, res) => {
const store = createStore(req);
//express does not touch routing. it delegates everything to react.
//I will just place the logic behind invoking loadData functions here.
//matchRoutes will look at the path and will return the array of components to be loaded.
//this is what matchRoutes function show `{ route: { loadData: [Function: loadData], path: '/users', component: [Object] },//component that we show
match: { path: '/users', url: '/users', isExact: true, params: {} } }
`
//
const promises = matchRoutes(Routes, req.path)
.map(({ route }) => {
return route.loadData ? route.loadData(store) : null;
}) //we got the array of loadData functions now we are invoking them
.map(promise => {
if (promise) {
return new Promise((resolve, reject) => {
promise.then(resolve).catch(resolve);
});
}
});
//Promise.all takes an array of promises and resolves when all of the items resolve
Promise.all(promises).then(()=>{
//here is when it is time to render your server-side code.
}).catch(e => console.log(e.message));
}