![](/img/trans.png)
[英]Should I use react-loadable or loadable-components for code splitting?
[英]Code splitting route components wrapped in a HOC with React Loadable
我在使用React Loadable和使用Webpack 3.11進行基於路由的代碼拆分時遇到了問題。
當我嘗試在服務器上呈現我的應用程序時,我的異步模塊會立即解析,而無需等待承諾。 因此,SSR輸出變為<div id="root"></div>
。
App.js:
const App = () => (
<Switch>
{routes.map((route, index) => (
<Route key={index} path={route.path} render={routeProps => {
const RouteComponent = route.component
return <RouteComponent {...routeProps} />
}} />
))}
</Switch>
)
我已經用React Loadable定義了異步路由組件,如下所示:
Routes.js
function Loading ({ error }) {
if (error) {
return 'Oh nooess!'
} else {
return <h3>Loading...</h3>
}
}
const Article = Loadable({
loader: () => import(/* webpackChunkName: "Article" */ '../components/contentTypes/Article'),
loading: Loading
})
const Page = Loadable({
loader: () => import(/* webpackChunkName: "Page" */ '../components/contentTypes/Page'),
loading: Loading,
render (loaded, props) {
let Component = WithSettings(loaded.default)
return <Component {...props}/>
}
})
export default [
{
path: `/:projectSlug/:env${getEnvironments()}/article/:articleSlug`,
component: Article,
exact: true
},
{
path: `/:projectSlug/:env${getEnvironments()}/:menuSlug?/:pageSlug?`,
component: Page
}
]
WithSettings.js
export default (WrappedComponent: any) => {
class WithSettings extends React.Component<WithSettingsProps, WithSettingsState> {
static displayName = `WithSettings(${WrappedComponent.displayName || WrappedComponent.name || 'Component'})`
state = {
renderWidth: 1200
}
componentDidMount () {
this.loadSettings({ match: { params: { projectSlug: '', env: '' } } })
window.addEventListener('resize', this.onResize)
this.onResize()
}
componentWillUnmount () {
if (isClient) {
window.removeEventListener('resize', this.onResize)
}
}
componentDidUpdate (oldProps) {
this.loadSettings(oldProps)
}
onResize = () => {
this.setState({ renderWidth: this.getLayoutWidth() })
}
getLayoutWidth () {
return (document.body && document.body.offsetWidth) || 0
}
loadSettings (oldProps) {
const { settings, request, getNewSettings } = this.props
const { projectSlug: oldProjectSlug, env: oldEnv } = oldProps.match.params
const { projectSlug: newProjectSlug, env: newEnv } = this.props.match.params
if (
(
oldProjectSlug !== newProjectSlug ||
oldEnv !== newEnv
) ||
(
settings === undefined ||
(request.networkStatus === 'ready')
)
) {
getNewSettings()
}
}
render () {
const { settings, request, history, location, match } = this.props
const { renderWidth } = this.state
if (!settings || !request || request.networkStatus === 'loading') {
return <div />
}
if (request.networkStatus === 'failed') {
return <ErrorBlock {...getErrorMessages(match.params, 'settings')[4044]} fullscreen match={match} />
}
return (
<WrappedComponent
settings={settings}
settingsRequest={request}
history={history}
location={location}
match={match}
renderWidth={renderWidth}
/>
)
}
}
hoistNonReactStatic(WithSettings, WrappedComponent)
return connect(mapStateToProps, mapDispatchToProps)(WithSettings)
}
我已經成功地縮小它的WithSettings
我使用包在我的路線組件HOC。如果我不使用WithSettings
HOC(與第二條路線),那么我的SSR輸出等待異步進口完成,並且服務器生成的html包含與路由相關的標記(好!)。 如果我確實使用HOC(與Page路由一樣),則該模塊會立即解析,並且我的SSR輸出變為<div id="root"></div
因為它不再等待動態導入完成才渲染。 問題是:我需要在所有路由中使用WithSettings HOC,因為它會從服務器中獲取渲染應用程序所需的數據。
誰能告訴我如何使用HOC 並將 React Loadable的async組件用於路由組件,從而使其在服務器上工作?
設法弄清楚了。
這是由於我的HOC。 在render方法中,當settings
或request
loading
未定義或request.networkStatus
時,它將返回<div />
。 事實證明,這跳了服務器端渲染。 刪除該塊足以使其正常工作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.