Борис Могила "Isomorphic React apps in production"
-
Upload
fwdays -
Category
Technology
-
view
848 -
download
1
Transcript of Борис Могила "Isomorphic React apps in production"
Борис Могила
RIA.com
Isomorphic React apps in production
100%
ізоморфний код
2
Клієнт
Сервер
Спільний кодСервер
для роботи
з даними
80% ізоморфного коду!3
● Webpack - білдер скриптів
Стек технологій:
● Redux - модель роботи з даними
● React-router - універсальний роутінг
● React - логіка виводу даних
● React-helmet - робота з SEO
4
Запит
Ініціалізація
store
Роутінг
(отримання
компонента)
Відпрацювання
всіх подій
(отримання даних)
Рендерінг
компонента
Відповідь
Логіка на сервері
5
Ініціалізація
store
Роутінг
(отримання
компонента)
Підключення
віртуального
дому до HTML
Натиснення на
посилання
Логіка в браузері
зміна HTML
6
7
● синхронізація state та history API
Ініціалізація store
● метод конфігурації store реалізуємо з
можливістю передачі:
○ даних для ініціалізації стану
○ history API
○ middlewares
● передача state на клієнт
8
9
Роутінг
● для отримання компонента використовуємо
метод match, як на клієнті, так і на сервері
● реалізація перенаправлень (redirect-ів) на рівні
отримання даних з сервера
● react-router не працює з регулярними виразами
10
● отримання компонента на клієнті:
match({routes, history}, (error, redirectLocation, renderProps) => {
render(
<Provider store={store}>
<Router {...renderProps}/>
</Provider>
, document.getElementById('content')
);
});
11
● ліниве завантаження (lazy-loading) реалізовуємо
на рівні роутінга
● require.ensure не працює на сервері
12
● ліниве завантаження (lazy-
loading):
const getMyComponent = (nextState, callback) =>
require.ensure(
[], (require) => {
callback(null,require("./MyComponent").default)
}
)
export default (
<Route path="/" component={Layout}>
<IndexRoute getComponent={getMyComponent}/>
</Route>
) 13
14
export default (seo) => (
<Helmet
title={seo.title}
meta={[
{"name": "description", "content": seo.text}
]}
/>
)
React не пристосований для роботи з тегом
head, тому доведеться використати додаткову
бібліотеку.
Робота з SEO:
15
Вивід SEO на сервері:
const {component} = this.props,
content = component ?
ReactDOM.renderToString(component) :
'',
head = Helmet.rewind();
● отримання потрібних даних:
16
● відображення в jsx:
return (
<html lang="en-us">
<head>
{head.title.toComponent()}
{head.meta.toComponent()}
</head>
<body>
// компонент і скрипти
</body>
</html>
);17
Отримання даних:
18
● використовуємо Promise.all для контролю
виконання всіх подій
● ізоморфний компонент повинен мати статичний
метод, в якому описано
○ виклик всіх подій для отримання даних
○ додаткова ізоморфна логіка
● повний url для отримання даних
19
static fetchData(props){
const promiseArray = [
seoAsyncAction (props);
];
return Promise.all(promiseArray);
}
20
export default const seoAsyncAction = ({dispatch}) => {
return superagent
.get(`https://dom.ria.com/getSeo/`)
.then((res) => {
return dispatch({
type: "GET_SEO",
payload: res.body
})
})
} 21
● логіку в браузері реалізуємо в методах
○ componentDidMount
○ componentWillReceiveProps
(не відпрацьовують на сервері)
22
● отримання даних при вставці компонента в DOM
componentDidMount(){
const {props} = this;
MyComponent.fetchData(props);
}
23
● оновлення даних при зміні параметрів сторінки
componentWillReceiveProps(nextProps){
if (/*ваше рішення оновлення даних */) {
MyComponent.fetchData(nextProps);
}
}
24
// ./fetchComponentData
export default (dispatch, props) => {
return Promise.all(
props.components
.filter(
component => typeof component.fetchData === 'function'
)
.map(component => component.fetchData(
{dispatch, ...props}
)));
}
● на сервері виконуємо статичний метод у всіх
потрібних компонентів
25
● формування відповіді
match({history, routes, req.originalUrl}, function (error, redirectLocation, renderProps){
fetchComponentData(store.dispatch, renderProps).then(() => {
component = (
<Provider store={store}>
<RouterContext {...renderProps} />
</Provider>
);
res.body = '<!doctype html>\n' +
renderToString(
<Html component={component} store={store} />
);
});
}); 26
Чому варто збирати серверний код?
27
● перший контакт з сервером тривалий
● при використанні лінивого завантаження без збірки код не буде
працювати на сервері
● можливість перегляду і контролю зібраного коду
28
Розширений і доповнений приклад
https://github.com/BoryaMogila/koa_react_redux
email: [email protected],
facebook: Boris Mogila
vk: Борис Могила
twitter: Borya Mogila
Контактні дані:
29
Дякую за увагу!
30