СоХабр закрыт.
С 13.05.2019 изменения постов больше не отслеживаются, и новые посты не сохраняются.
static async getInitialProps()
, в котором предлагается проводить асинхронную загрузку данных. Такое решение не лишено недостатков. Например, этот метод статический, следовательно не имеет доступ к экземпляру компонента, метод реализован только для компонента самого верхнего уровня и отсутствует у вложенных компонентов. Решение с Apollo graphql client может быть использовано для компонента произвольного уровня вложенности.ApolloProvider client={client}
и асинхронное получение данных функцией await getDataFromTree(App)
. За кадром ApolloProvider определяет какие запросы нужно выполнить для рендеринга компонентов с учетом выбранного роута, выполняет эти запросы и передает данные в компоненты при рендеринге....
import AppRouter from './AppRouter';
import assets from '../build/asset-manifest.json';
module.exports = async (req, res, next) => {
const client = new ApolloClient({
ssrMode: true,
link: createHttpLink({
uri: 'https://api.graph.cool/simple/v1/ciyz901en4j590185wkmexyex',
headers: {
cookie: req.header('Cookie'),
},
fetch,
}),
cache: new InMemoryCache(),
});
const context = {};
const App = <ApolloProvider client={client}>
<StaticRouter location={req.url} context={context}>
<AppRouter />
</StaticRouter>
</ApolloProvider>;
await getDataFromTree(App)
const html = ReactDOMServer.renderToString((App));
const initialState = client.extract();
res.write(`
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Conduit</title>
<link rel="stylesheet" href="/${assets['main.css']}">
</head>
<body>
<script>
// WARNING: See the following for security issues around embedding JSON in HTML:
// http://redux.js.org/docs/recipes/ServerRendering.html#security-considerations
window.__APOLLO_STATE__ = ${JSON.stringify(initialState, null, 2).replace(/</g, '\\u003c')};
</script>
<div id="app">${html}</div>
<script src="/${assets['main.js']}"></script>
</body>
</html>
`);
res.end();
}
cache: new InMemoryCache().restore(window.__APOLLO_STATE__)
.import App from './App';
import { ApolloClient } from 'apollo-client';
import { HttpLink } from 'apollo-link-http';
import { onError } from 'apollo-link-error';
import { ApolloLink } from 'apollo-link';
import { InMemoryCache } from "apollo-cache-inmemory";
const client = new ApolloClient({
link: ApolloLink.from([
onError(({ graphQLErrors, networkError }) => {
if (graphQLErrors)
graphQLErrors.map(({ message, locations, path }) =>
console.log(
`[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`,
),
);
if (networkError) console.log(`[Network error]: ${networkError}`);
}),
new HttpLink({
uri: 'https://api.graph.cool/simple/v1/ciyz901en4j590185wkmexyex',
// credentials: 'same-origin'
})
]),
cache: new InMemoryCache().restore(window.__APOLLO_STATE__),
});
hydrate(<App client={client} />, document.getElementById('app'));
комментарии (0)