СоХабр закрыт.
С 13.05.2019 изменения постов больше не отслеживаются, и новые посты не сохраняются.
static async getInitialProps()
, в котором предлагается проводить асинхронную загрузку данных. Такое решение не лишено недостатков. Например, этот метод статический, следовательно не имеет доступ к экземпляру компонента, метод реализован только для компонента самого верхнего уровня и отсутствует у вложенных компонентов. Решение с Apollo graphql client может быть использовано для компонента произвольного уровня вложенности.ApolloProvider client={client}
и асинхронное получение данных функцией await getDataFromTree(App)
. За кадром ApolloProvider определяет какие запросы нужно выполнить для рендеринга компонентов с учетом выбранного роута, выполняет эти запросы и передает в компоненты при рендеринге.import React from 'react';
import ReactDOMServer from 'react-dom/server';
import { StaticRouter, Switch, Route, } from 'react-router-dom';
import fetch from 'node-fetch';
import { ApolloProvider, getDataFromTree, renderToStringWithData } from 'react-apollo';
import { ApolloClient } from 'apollo-client';
import { createHttpLink } from 'apollo-link-http';
import { InMemoryCache } from "apollo-cache-inmemory";
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}>
<Layout>
<Switch>
<Route exact path='/' component={ AllUsers } />
<Route exact path='/posts' component={ TopPosts } />
<Route exact path='/post/:postId' component={ Post } />
<Route exact path='/user/:userId' component={ NewPost } />
</Switch>
</Layout>
</StaticRouter>
</ApolloProvider>;
await getDataFromTree(App)
const html = ReactDOMServer.renderToString((App));
const initialState = client.extract();
res.write(`
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="/${assets['main.css']}">
</head>
<body>
<script>
window.__PRELOADED_STATE__ = ${JSON.stringify(initialState, null, 2).replace(/</g, '\\u003c')};
</script>
<section id="app">${html}</section>
<script src="/${assets['main.js']}"></script>
</body>
</html>
`);
res.end();
}
cache: new InMemoryCache().restore(window.__PRELOADED_STATE__)
.import React from 'react';
import { Route, Switch, BrowserRouter } from 'react-router-dom';
import { ApolloProvider } from 'react-apollo';
import ApolloClient from 'apollo-boost';
import { InMemoryCache } from "apollo-cache-inmemory";
...
const client = new ApolloClient({
uri: 'https://api.graph.cool/simple/v1/ciyz901en4j590185wkmexyex',
cache: new InMemoryCache().restore(window.__PRELOADED_STATE__),
});
const App = () => (
<ApolloProvider client={client}>
<BrowserRouter>
<Layout>
<Switch>
<Route exact path='/' component={ AllUsers } />
<Route exact path='/posts' component={ TopPosts } />
<Route exact path='/post/:postId' component={ Post } />
<Route exact path='/user/:userId' component={ NewPost } />
</Switch>
</Layout>
</BrowserRouter>
</ApolloProvider>
);
export default App;
комментарии (0)