我用React,react-router,@ loadable / component创建了一个项目。
现在,我正在尝试将SSR添加到该项目中。 我用react-router进行服务器端渲染。
然后我添加了@ loadable / component来导入所有页面组件:
import loadable from '@loadable/component';
const routersConfig = [
{
path: '/',
component: loadable(() => import('./Home')),
exact: true,
},
{
path: '/2',
component: loadable(() => import('./Home2')),
exact: true,
},
];
然后我添加了所有以下代码部分:https://www.smooth-code.com/open-source/loadable-components/docs/server-side-rendering/
现在它可以工作了。 但这可以解决问题:加载时内容闪烁。
我如何理解页面的加载过程:
我拍摄了一段视频来说明这个过程。 (对于质量,我感到抱歉,stackoverflow禁止文件大小超过2MB)。我正在限制网络速度以想象所有页面的下载过程。
我的问题是为什么内容消失了?如何解决?
我的代码
server.js
const sheetStyledComponents = new ServerStyleSheet();
const sheetsJssRegistry = createSheetsRegistry();
const statsFile = path.resolve(process.cwd(), './build-ssr/dist/loadable-stats.json');
const extractor = new ChunkExtractor({
statsFile,
entrypoints: [
'app',
'normalize',
],
});
try {
const client = ApolloSSRClient();
const tree = (
<ApolloProvider client={client}>
<ApplyTheme sheetsRegistry={sheetsJssRegistry}>
<StaticRouter location={req.url}>
<Home />
</StaticRouter>
</ApplyTheme>
</ApolloProvider>
);
// there is combination of Apollo graphql, jss, styledComponent functions
const body = await getMarkupFromTree({
renderFunction: flow(
sheetStyledComponents.collectStyles.bind(sheetStyledComponents),
extractor.collectChunks.bind(extractor),
renderToString
),
tree,
});
const scriptTags = extractor.getScriptTags();
// It isn't used yet
const linkTags = extractor.getLinkTags();
const styleTags = sheetStyledComponents.getStyleTags();
const html = (await rawHtml)
.replace(
'</head>',
`
${styleTags}
<style type="text/css" id='jss-server-side-styles'>
${sheetsJssRegistry.toString()}
</style>
<script>
window.__APOLLO_STATE__ = ${JSON.stringify(client.extract())};
</script>
${scriptTags}
</head>
`
)
.replace('<div id="app"></div>', `<div id="app">${body}</div>`);
res.send(html);
index.jsx
const SSRApp = (
<ApolloProvider client={ApolloClient}>
<ApplyTheme>
<BrowserRouter>
<App />
</BrowserRouter>
</ApplyTheme>
</ApolloProvider>
);
loadableReady(() => (
ReactDOM.hydrate(
SSRApp,
document.getElementById('app'),
)
));
答案 0 :(得分:1)
这是我的错。
该应用的水化版本包含 BrowserRouter->交换机->路由器->主页
SSR版本仅包含 StaticRouter->主页
因此,在渲染SSR版本后,react删除了所有DOM并使用Router创建了一个新的DOM。
答案 1 :(得分:0)
我在server.js中进行了更改。它对我有用
您可能是(server / index.js或server.js或server / app.js..etc)
import Express from 'express';
import Loadable from 'react-loadable';
// from //
app.listen(3000, () => {
console.log('app now listening on port', port);
});
// to //
import Loadable from 'react-loadable';
Loadable.preloadAll().then(() => {
app.listen(port, () => {
console.log('app now listening on port', port);
});
});
进一步了解配置you can see
从服务器渲染正确内容的第一步是确保在渲染时,所有可加载组件均已加载。
为此,可以使用Loadable.preloadAll方法。它返回一个承诺,当所有可加载组件准备就绪时,它将解决。