Skip to content

Commit 3bfd3fe

Browse files
committed
feat: [LazyComponent] export LazyComponentOnLoadParams
1 parent 524401d commit 3bfd3fe

File tree

4 files changed

+172
-22
lines changed

4 files changed

+172
-22
lines changed

src/components/LazyComponent/index.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
import React from 'react';
22
import { SuspenseWrap } from './SuspenseWrap';
3-
import { LazyComponentProps, LazyComponentPropsWithCode } from './interface';
3+
import {
4+
LazyComponentProps,
5+
LazyComponentPropsWithCode,
6+
LazyComponentOnLoadParams,
7+
} from './interface';
48
import { useComponents } from '../ComponentsProvider/useComponents';
59

6-
export type { LazyComponentProps };
10+
export type { LazyComponentProps, LazyComponentOnLoadParams };
711

812
export const LazyComponentWithCode: React.FC<LazyComponentPropsWithCode> = (props) => {
913
const { code, fallback, onLoad, onError, ...rest } = props;

src/components/LazyComponent/interface.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,14 @@ export interface LazyComponentPropsWithComponent extends LazyComponentBaseProps
88
component: React.ComponentType | null;
99
}
1010

11+
export interface LazyComponentOnLoadParams {
12+
async: boolean;
13+
component: React.ComponentType<any>;
14+
}
15+
1116
export interface LazyComponentPropsWithCode extends LazyComponentBaseProps {
1217
code: string;
13-
onLoad?: (e: { async: boolean; component: React.ComponentType<any> }) => void;
18+
onLoad?: (e: LazyComponentOnLoadParams) => void;
1419
}
1520

1621
export type LazyComponentProps = LazyComponentPropsWithComponent | LazyComponentPropsWithCode;

src/index.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,11 @@ export { importScript } from './utils/importScript';
66
export { lazyComponent } from './utils/lazyComponent';
77
export { mountComponent } from './utils/mountComponent';
88

9-
/* eslint-disable import/no-cycle */
109
export { ComponentsProvider, useComponents } from './components/ComponentsProvider';
1110
export type { ComponentsProviderProps, ComponentsMap } from './components/ComponentsProvider';
1211

1312
export { LazyComponent } from './components/LazyComponent';
14-
export type { LazyComponentProps } from './components/LazyComponent';
15-
/* eslint-enable import/no-cycle */
13+
export type { LazyComponentProps, LazyComponentOnLoadParams } from './components/LazyComponent';
1614

1715
export { Avatar } from './components/Avatar';
1816
export type { AvatarProps, AvatarSize, AvatarShape } from './components/Avatar';

storybook/stories/ComponentProvider.stories.tsx

Lines changed: 159 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
import React from 'react';
1+
import React, { useEffect } from 'react';
22
import { Meta } from '@storybook/react/types-6-0';
33

44
import * as ChatUI from '../../src';
5-
import { ComponentsMap } from '../../src';
5+
import { ComponentsMap, LazyComponentOnLoadParams } from '../../src';
66

7-
const { ComponentsProvider, LazyComponent } = ChatUI;
7+
const { ComponentsProvider, LazyComponent, useComponents } = ChatUI;
88

99
export default {
1010
title: 'ComponentsProvider',
@@ -89,24 +89,51 @@ export const LocalComponent = () => (
8989
</ComponentsProvider>
9090
);
9191

92-
function TestAsyncComponent() {
92+
function LazySlot() {
93+
const data = { list: [{ title: 'item-1' }, { title: 'item-2' }] };
9394
return (
94-
<div>
95-
<h1>Example:</h1>
96-
<LazyComponent
97-
code="slot"
98-
data={{ list: [{ title: 'item-1' }, { title: 'item-2' }] }}
99-
meta={{}}
100-
ctx={ctx}
101-
onLoad={(a: any) => console.log('onLoad:', a)}
102-
/>
103-
</div>
95+
<LazyComponent
96+
code="slot"
97+
data={data}
98+
meta={{}}
99+
ctx={ctx}
100+
onLoad={(r: LazyComponentOnLoadParams) => console.log('slot - onLoad:', r)}
101+
/>
102+
);
103+
}
104+
105+
function LazyRecommend() {
106+
const data = {
107+
recommends: [
108+
{
109+
knowledgeId: 'q1',
110+
title: 'Question 1',
111+
},
112+
{
113+
knowledgeId: 'q2',
114+
title: 'Question 2',
115+
},
116+
{
117+
knowledgeId: 'q3',
118+
title: 'Question 3',
119+
},
120+
],
121+
};
122+
return (
123+
<LazyComponent
124+
code="recommend"
125+
data={data}
126+
meta={{}}
127+
ctx={ctx}
128+
onLoad={(r: any) => console.log('recommend - onLoad:', r)}
129+
onError={(e: Error) => console.log('recommend - onError:', e)}
130+
/>
104131
);
105132
}
106133

107134
export const AsyncComponent = () => (
108135
<ComponentsProvider components={components}>
109-
<TestAsyncComponent />
136+
<LazySlot />
110137
</ComponentsProvider>
111138
);
112139

@@ -141,7 +168,7 @@ function TestComponentHasError() {
141168
code="slot"
142169
onError={(err, errInfo) => {
143170
setErrMsg(err.message);
144-
console.log(errInfo);
171+
console.log(222, err, errInfo);
145172
}}
146173
/>
147174
{errMsg && <pre>Error message: {errMsg}</pre>}
@@ -164,6 +191,7 @@ function TestErrorUrl() {
164191
code="error-url"
165192
onError={(err) => {
166193
setErrMsg(err.message);
194+
console.log(222, err.message);
167195
}}
168196
/>
169197
{errMsg && <pre>Error message: {errMsg}</pre>}
@@ -221,3 +249,118 @@ export const AsyncDecorator = () => (
221249
<TestAsyncDecorator />
222250
</ComponentsProvider>
223251
);
252+
253+
function TestAddComponent() {
254+
const { addComponent, hasComponent } = useComponents();
255+
const forceUpdate = useForceUpdate();
256+
257+
function addRecommend() {
258+
if (!hasComponent('recommend')) {
259+
addComponent('recommend', {
260+
name: 'AlimeComponentRecommend',
261+
url: '//g.alicdn.com/alime-components/recommend/0.1.0/index.js',
262+
});
263+
// forceUpdate();
264+
}
265+
}
266+
267+
const onClick = React.useCallback(() => {
268+
forceUpdate();
269+
}, [forceUpdate]);
270+
271+
function handleImgLoad(e: any) {
272+
console.log('img load', e);
273+
}
274+
275+
return (
276+
<div>
277+
<img onLoad={handleImgLoad} src="11" alt="" />
278+
<button type="button" onClick={onClick}>
279+
update inner
280+
</button>
281+
<button onClick={addRecommend}>add recommend</button>
282+
<LazyRecommend />
283+
</div>
284+
);
285+
}
286+
287+
function useForceUpdate() {
288+
const [, forceUpdate] = React.useState(false);
289+
290+
return React.useCallback(() => {
291+
forceUpdate((s) => !s);
292+
}, []);
293+
}
294+
295+
export const AddComponent = () => {
296+
const forceUpdate = useForceUpdate();
297+
const renderCount = React.useRef(0);
298+
299+
React.useEffect(() => {
300+
renderCount.current += 1;
301+
});
302+
303+
const onClick = React.useCallback(() => {
304+
forceUpdate();
305+
}, [forceUpdate]);
306+
307+
return (
308+
<div>
309+
<button type="button" onClick={onClick}>
310+
update
311+
</button>
312+
<div>Render count: {renderCount.current}</div>
313+
314+
<ComponentsProvider components={components}>
315+
<TestAddComponent />
316+
</ComponentsProvider>
317+
318+
<ComponentsProvider components={components}>
319+
<LazySlot />
320+
</ComponentsProvider>
321+
</div>
322+
);
323+
};
324+
325+
export const MutableComponents = () => {
326+
const [myComponents, setMyMyComponents] = React.useState({});
327+
const forceUpdate = useForceUpdate();
328+
329+
function addSlot() {
330+
setMyMyComponents({
331+
...myComponents,
332+
slot: {
333+
name: 'AlimeComponentSlot',
334+
url: '//g.alicdn.com/alime-components/slot/0.1.3/index.js',
335+
},
336+
});
337+
}
338+
339+
function addRecommend() {
340+
setMyMyComponents({
341+
...myComponents,
342+
recommend: {
343+
name: 'AlimeComponentRecommend',
344+
url: '//g.alicdn.com/alime-components/recommend/0.1.0/index.js',
345+
},
346+
});
347+
}
348+
349+
const onClick = React.useCallback(() => {
350+
forceUpdate();
351+
}, [forceUpdate]);
352+
353+
return (
354+
<div>
355+
<button type="button" onClick={onClick}>
356+
update
357+
</button>
358+
<button onClick={addSlot}>add slot</button>
359+
<button onClick={addRecommend}>add recommend</button>
360+
<ComponentsProvider components={myComponents}>
361+
<LazySlot />
362+
<LazyRecommend />
363+
</ComponentsProvider>
364+
</div>
365+
);
366+
};

0 commit comments

Comments
 (0)