Skip to content

Commit 3469d41

Browse files
authored
Merge pull request #2123 from didi/fix-async-suspense
fix async-suspense
2 parents 4b302d5 + 3060843 commit 3469d41

File tree

6 files changed

+36
-30
lines changed

6 files changed

+36
-30
lines changed

packages/core/src/platform/createApp.ios.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,17 +73,20 @@ export default function createApp (options) {
7373
children
7474
)
7575
}
76+
const getComponent = () => {
77+
return item.displayName ? item : item()
78+
}
7679
if (key === initialRouteName) {
7780
return createElement(Stack.Screen, {
7881
name: key,
79-
getComponent: () => item(),
82+
getComponent,
8083
initialParams,
8184
layout: headerLayout
8285
})
8386
}
8487
return createElement(Stack.Screen, {
8588
name: key,
86-
getComponent: () => item(),
89+
getComponent,
8790
layout: headerLayout
8891
})
8992
})

packages/core/src/platform/patch/getDefaultOptions.ios.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,8 @@ function createEffect (proxy, componentsMap) {
5353
const appComponentsMap = global.__appComponentsMap || {}
5454
const generichash = proxy.target.generichash || ''
5555
const genericComponentsMap = global.__mpxGenericsMap?.[generichash] || {}
56-
const componentGetter = componentsMap[tagName] || genericComponentsMap[tagName] || appComponentsMap[tagName]
57-
return componentGetter ? componentGetter() : getByPath(ReactNative, tagName)
56+
const component = componentsMap[tagName] || genericComponentsMap[tagName] || appComponentsMap[tagName]
57+
return component ? component.displayName ? component : component() : getByPath(ReactNative, tagName)
5858
}
5959
const innerCreateElement = (type, ...rest) => {
6060
if (!type) return null

packages/webpack-plugin/lib/react/script-helper.js

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,13 @@ function getAsyncChunkName (chunkName) {
2121
return ''
2222
}
2323

24-
function getAsyncSuspense (type, moduleId, componentRequest, componentName, chunkName, fallback, loading) {
24+
function getAsyncSuspense (type, moduleId, componentRequest, componentName, chunkName, getFallback, getLoading) {
2525
return `getAsyncSuspense({
2626
type: ${JSON.stringify(type)},
2727
moduleId: ${JSON.stringify(moduleId)},
2828
chunkName: ${JSON.stringify(chunkName)},
29-
loading: ${loading},
30-
fallback: ${fallback},
29+
getFallback: ${getFallback},
30+
getLoading: ${getLoading},
3131
getChildren () {
3232
return import(${getAsyncChunkName(chunkName)}${componentRequest}).then(function (res) {
3333
return getComponent(res, {displayName: ${JSON.stringify(componentName)}})
@@ -61,9 +61,9 @@ function buildPagesMap ({ localPagesMap, loaderContext, jsonConfig, rnConfig })
6161
const pageRequest = stringifyRequest(loaderContext, pageCfg.resource)
6262
if (pageCfg.async) {
6363
const moduleId = mpx.getModuleId(pageCfg.resource)
64-
const fallback = rnConfig.asyncChunk && rnConfig.asyncChunk.fallback && getComponent(stringifyRequest(loaderContext, addQuery(rnConfig.asyncChunk.fallback, { isComponent: true })), 'PageFallback')
65-
const loading = rnConfig.asyncChunk && rnConfig.asyncChunk.loading && getComponent(stringifyRequest(loaderContext, addQuery(rnConfig.asyncChunk.loading, { isComponent: true })), 'PageLoading')
66-
pagesMap[pagePath] = getComponentGetter(getAsyncSuspense('page', moduleId, pageRequest, 'Page', pageCfg.async, fallback, loading))
64+
const getFallback = rnConfig.asyncChunk && rnConfig.asyncChunk.fallback && getComponentGetter(getComponent(stringifyRequest(loaderContext, addQuery(rnConfig.asyncChunk.fallback, { isComponent: true })), 'PageFallback'))
65+
const getLoading = rnConfig.asyncChunk && rnConfig.asyncChunk.loading && getComponentGetter(getComponent(stringifyRequest(loaderContext, addQuery(rnConfig.asyncChunk.loading, { isComponent: true })), 'PageLoading'))
66+
pagesMap[pagePath] = getAsyncSuspense('page', moduleId, pageRequest, 'Page', pageCfg.async, getFallback, getLoading)
6767
} else {
6868
// 为了保持小程序中app->page->component的js执行顺序,所有的page和component都改为require引入
6969
pagesMap[pagePath] = getComponentGetter(getComponent(pageRequest, 'Page'))
@@ -91,7 +91,7 @@ function buildComponentsMap ({ localComponentsMap, builtInComponentsMap, loaderC
9191
if (componentCfg.async) {
9292
const moduleId = mpx.getModuleId(componentCfg.resource)
9393
const placeholder = jsonConfig.componentPlaceholder && jsonConfig.componentPlaceholder[componentName]
94-
let fallback
94+
let getFallback
9595
if (placeholder) {
9696
if (localComponentsMap[placeholder]) {
9797
const placeholderCfg = localComponentsMap[placeholder]
@@ -101,11 +101,11 @@ function buildComponentsMap ({ localComponentsMap, builtInComponentsMap, loaderC
101101
new Error(`[json processor][${loaderContext.resource}]: componentPlaceholder ${placeholder} should not be a async component, please check!`)
102102
)
103103
}
104-
fallback = getComponent(placeholderRequest, placeholder)
104+
getFallback = getComponentGetter(getComponent(placeholderRequest, placeholder))
105105
} else {
106106
const tag = `mpx-${placeholder}`
107107
if (isBuildInReactTag(tag)) {
108-
fallback = getBuiltInComponent(getBuiltInComponentRequest(tag))
108+
getFallback = getComponentGetter(getBuiltInComponent(getBuiltInComponentRequest(tag)))
109109
} else {
110110
loaderContext.emitError(
111111
new Error(`[json processor][${loaderContext.resource}]: componentPlaceholder ${placeholder} is not built-in component, please check!`)
@@ -117,7 +117,7 @@ function buildComponentsMap ({ localComponentsMap, builtInComponentsMap, loaderC
117117
new Error(`[json processor][${loaderContext.resource}]: ${componentName} has no componentPlaceholder, please check!`)
118118
)
119119
}
120-
componentsMap[componentName] = getComponentGetter(getAsyncSuspense('component', moduleId, componentRequest, componentName, componentCfg.async, fallback))
120+
componentsMap[componentName] = getAsyncSuspense('component', moduleId, componentRequest, componentName, componentCfg.async, getFallback)
121121
} else {
122122
componentsMap[componentName] = getComponentGetter(getComponent(componentRequest, componentName))
123123
}

packages/webpack-plugin/lib/runtime/components/react/mpx-async-suspense.tsx

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -99,20 +99,20 @@ interface AsyncSuspenseProps {
9999
chunkName: string
100100
moduleId: string
101101
innerProps: any,
102-
loading?: ComponentType<unknown>
103-
fallback?: ComponentType<unknown>
102+
getLoading?: () => ComponentType<unknown>
103+
getFallback?: () => ComponentType<unknown>
104104
getChildren: () => Promise<ReactNode>
105105
}
106106

107107
type ComponentStauts = 'pending' | 'error' | 'loaded'
108108

109109
const AsyncSuspense: React.FC<AsyncSuspenseProps> = ({
110110
type,
111-
innerProps,
112111
chunkName,
113112
moduleId,
114-
loading,
115-
fallback,
113+
innerProps,
114+
getLoading,
115+
getFallback,
116116
getChildren
117117
}) => {
118118
const [status, setStatus] = useState<ComponentStauts>('pending')
@@ -158,19 +158,20 @@ const AsyncSuspense: React.FC<AsyncSuspenseProps> = ({
158158
return createElement(Comp, innerProps)
159159
} else if (status === 'error') {
160160
if (type === 'page') {
161-
fallback = fallback || DefaultFallback
161+
const fallback = getFallback ? getFallback() : DefaultFallback
162162
return createElement(fallback as ComponentType<DefaultFallbackProps>, { onReload: reloadPage })
163163
} else {
164-
return fallback ? createElement(fallback, innerProps) : null
164+
return getFallback ? createElement(getFallback(), innerProps) : null
165165
}
166166
} else {
167167
if (!loadChunkPromise.current) {
168168
loadChunkPromise.current = getChildren()
169169
}
170170
if (type === 'page') {
171-
return createElement(loading || DefaultLoading)
171+
const loading = getLoading ? getLoading() : DefaultLoading
172+
return createElement(loading)
172173
} else {
173-
return fallback ? createElement(fallback, innerProps) : null
174+
return getFallback ? createElement(getFallback(), innerProps) : null
174175
}
175176
}
176177
}

packages/webpack-plugin/lib/runtime/optionProcessorReact.d.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,9 @@ interface AsyncSuspenseProps {
1818
type: 'component' | 'page'
1919
chunkName: string
2020
moduleId: string
21-
innerProps: any
22-
loading: ComponentType<unknown>
23-
fallback: ComponentType<unknown>
21+
getFallback?: () => ComponentType<unknown>
22+
getLoading?: () => ComponentType<unknown>
2423
getChildren: () => Promise<AsyncModule>
2524
}
2625

27-
export function getAsyncSuspense(props: AsyncSuspenseProps): ReactNode
26+
export function getAsyncSuspense (props: AsyncSuspenseProps): ReactNode

packages/webpack-plugin/lib/runtime/optionProcessorReact.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,23 +10,26 @@ export function getComponent (component, extendOptions) {
1010
}
1111

1212
export function getAsyncSuspense (commonProps) {
13+
let result
1314
if (commonProps.type === 'component') {
14-
return memo(forwardRef(function (props, ref) {
15+
result = memo(forwardRef(function (props, ref) {
1516
return createElement(AsyncSuspense,
1617
extend(commonProps, {
1718
innerProps: Object.assign({}, props, { ref })
1819
})
1920
)
2021
}))
2122
} else {
22-
return function (props) {
23+
result = memo(function (props) {
2324
return createElement(AsyncSuspense,
2425
extend(commonProps, {
2526
innerProps: props
2627
})
2728
)
28-
}
29+
})
2930
}
31+
result.displayName = 'AsyncSuspenseHOC'
32+
return result
3033
}
3134

3235
export function getLazyPage (getComponent) {

0 commit comments

Comments
 (0)