Kamil Płaczek: Server-side rendering niesie ze sobą liczne korzyści, o których nietrudno zapomnieć w świecie zdominowanym przez aplikacje typu single-page. Uruchomienie naszego SPA na serwerze może nie być jednak tak proste, jak pozornie się wydaje. Porozmawiamy o problemach, z którymi przyjdzie zmierzyć się programiście podczas implementacji SSR, a o których nie zawsze przeczytamy w sekcji "Getting started" dokumentacji naszej ulubionej biblioteki. Uwierzytelnianie, routing czy komunikacja z backendem – to niektóre z tematów, które poruszone zostaną podczas prezentacji na przykładzie Reacta i Express.js.
34. src/client/index.js
import {createAppStore} from './create-store';
const store = createAppStore(window.APP_STATE || {});
ReactDOM.hydrate(
<Provider store={store}>
<BrowserRouter>
<App />
</BrowserRouter>
</Provider>,
document.getElementById('root')
);
stworzenie store + odtworzenie stanu z ssr
35. src/server/index.js
import {createAppStore} from '../client/create-store';
. . .
app.get('*', async (req, res) => {
const store = createAppStore({});
const matchedRoute = routes.find(route => matchPath(req.path, route));
if (matchedRoute) {
if (matchedRoute.component && matchedRoute.component.loadData) {
await matchedRoute.component.loadData(store);
}
. . .
} else {
const state = store.getState();
const html = `<!DOCTYPE html>
. . .
<div id="root">${appString}</div>
<script>
window.APP_STATE = ${JSON.stringify(state)};
</script>
. . .
}
});
stworzenie store + inicjalizacja stanu podczas ssr
36. src/server/index.js
import {createAppStore} from '../client/create-store';
. . .
app.get('*', async (req, res) => {
const store = createAppStore({});
const matchedRoute = routes.find(route => matchPath(req.path, route));
if (matchedRoute) {
if (matchedRoute.component && matchedRoute.component.loadData) {
await matchedRoute.component.loadData(store);
}
. . .
} else {
const state = store.getState();
const html = `<!DOCTYPE html>
. . .
<div id="root">${appString}</div>
<script>
window.APP_STATE = ${JSON.stringify(state)};
</script>
. . .
}
});
stworzenie store + inicjalizacja stanu podczas ssr
37. src/server/index.js
import {createAppStore} from '../client/create-store';
. . .
app.get('*', async (req, res) => {
const store = createAppStore({});
const matchedRoute = routes.find(route => matchPath(req.path, route));
if (matchedRoute) {
if (matchedRoute.component && matchedRoute.component.loadData) {
await matchedRoute.component.loadData(store);
}
. . .
} else {
const state = store.getState();
const html = `<!DOCTYPE html>
. . .
<div id="root">${appString}</div>
<script>
window.APP_STATE = ${JSON.stringify(state)};
</script>
. . .
}
});
stworzenie store + inicjalizacja stanu podczas ssr
44. Problem 4: Uwierzytelnianie
• Jak renderować zawartość wymagającą autoryzacji? 🔐
Fetch token from the
server
Save token in
persistent storage
Pass token to the
server on requests
Authenticate &
authorize server-side