@cqsjjb/jjb-cloud-component 0.0.7-experimental.3 → 0.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -11,9 +11,21 @@ interface ComponentProps {
11
11
  */
12
12
  export function useUnMountCloudComponentStyle (styleId: string): void;
13
13
 
14
+ /**
15
+ * @description 云组件默认内置依赖项
16
+ * 所有云组件都可以直接使用这些依赖,无需手动传递
17
+ */
18
+ interface DefaultDependencies {
19
+ 'react': any;
20
+ 'react-dom': any;
21
+ '@cqsjjb/jjb-common-lib': any;
22
+ }
23
+
14
24
  interface CloudComponentProps extends ComponentProps {
15
- // 组件依赖
16
- dependencies?: { [ p: string ]: string }
25
+ // 组件依赖,支持函数引用(如require()的结果)
26
+ // 默认内置依赖:react, react-dom, @cqsjjb/jjb-common-lib
27
+ // 用户自定义依赖会与默认依赖合并,同名依赖会被覆盖
28
+ dependencies?: { [ p: string ]: any }
17
29
  // 组件资源地址
18
30
  from: string;
19
31
  // 缓存
@@ -1,6 +1,7 @@
1
1
  import React from 'react';
2
+ import ReactDOM from 'react-dom';
2
3
 
3
- import { tools } from '@cqsjjb/jjb-common-lib';
4
+ import * as jjbCommonLib from '@cqsjjb/jjb-common-lib';
4
5
 
5
6
  import ImportCloudComponent from './import-cloud-component';
6
7
 
@@ -19,6 +20,9 @@ export function useUnMountCloudComponentStyle(styleId) {
19
20
  /**
20
21
  * @description 云组件
21
22
  * @param props {object} 组件props
23
+ * @param props.dependencies {object} 自定义依赖项,会与默认依赖项合并
24
+ * @note 默认内置依赖项:react, react-dom, @cqsjjb/jjb-common-lib
25
+ * @note 用户自定义依赖项会覆盖同名的默认依赖项
22
26
  */
23
27
  export default function CloudComponent(props) {
24
28
  let styleId;
@@ -27,7 +31,7 @@ export default function CloudComponent(props) {
27
31
  from,
28
32
  cache,
29
33
  headers,
30
- dependencies = [],
34
+ dependencies = {},
31
35
  initialize,
32
36
  componentRef,
33
37
  componentKey,
@@ -39,10 +43,74 @@ export default function CloudComponent(props) {
39
43
  onUpdated
40
44
  } = props;
41
45
 
46
+ // 默认内置依赖项,所有云组件都可以使用
47
+ const defaultDependencies = {
48
+ 'react': React,
49
+ 'react-dom': ReactDOM,
50
+ 'jjbCommonLib': jjbCommonLib,
51
+ '@cqsjjb/jjb-common-lib': jjbCommonLib
52
+ };
53
+
54
+ // 合并默认依赖和用户自定义依赖,用户依赖优先级更高
55
+ const mergedDependencies = React.useMemo(() => {
56
+ return {
57
+ ...defaultDependencies,
58
+ ...dependencies
59
+ };
60
+ }, [dependencies]);
61
+
62
+ // 使用 useMemo 来稳定化 mergedDependencies 引用,避免不必要的重新渲染
63
+ const stableDependencies = React.useMemo(() => {
64
+ return mergedDependencies;
65
+ }, [mergedDependencies]);
66
+
67
+ // 使用 useRef 来跟踪 dependencies 的变化,避免因对象引用变化导致的重新渲染
68
+ const prevDependenciesRef = React.useRef();
69
+ const shouldReloadDependencies = React.useMemo(() => {
70
+ if (!prevDependenciesRef.current) {
71
+ prevDependenciesRef.current = mergedDependencies;
72
+ return true;
73
+ }
74
+
75
+ // 比较 dependencies 的键和值
76
+ const prevKeys = Object.keys(prevDependenciesRef.current);
77
+ const currentKeys = Object.keys(mergedDependencies);
78
+
79
+ if (prevKeys.length !== currentKeys.length) {
80
+ prevDependenciesRef.current = mergedDependencies;
81
+ return true;
82
+ }
83
+
84
+ for (const key of currentKeys) {
85
+ if (prevDependenciesRef.current[key] !== mergedDependencies[key]) {
86
+ prevDependenciesRef.current = mergedDependencies;
87
+ return true;
88
+ }
89
+ }
90
+
91
+ return false;
92
+ }, [mergedDependencies]);
93
+
94
+ // 使用 useRef 来存储回调函数,避免因回调函数重新创建导致的重新渲染
95
+ const onLoadStartRef = React.useRef(onLoadStart);
96
+ const onLoadEndRef = React.useRef(onLoadEnd);
97
+ const onDestroyRef = React.useRef(onDestroy);
98
+
42
99
  React.useEffect(() => {
100
+ onLoadStartRef.current = onLoadStart;
101
+ onLoadEndRef.current = onLoadEnd;
102
+ onDestroyRef.current = onDestroy;
103
+ });
104
+
105
+ React.useEffect(() => {
106
+ // 只有当 dependencies 真正发生变化时才重新加载
107
+ if (!shouldReloadDependencies && prevDependenciesRef.current) {
108
+ return;
109
+ }
110
+
43
111
  async function load() {
44
112
  try {
45
- onLoadStart && onLoadStart();
113
+ onLoadStartRef.current && onLoadStartRef.current();
46
114
  const {
47
115
  module,
48
116
  styleId: _styleId,
@@ -51,25 +119,25 @@ export default function CloudComponent(props) {
51
119
  from,
52
120
  cache,
53
121
  headers,
54
- dependencies
122
+ dependencies: stableDependencies
55
123
  });
56
124
 
57
125
  styleId = _styleId;
58
126
 
59
127
  setComponent(() => {
60
- onLoadEnd && onLoadEnd();
128
+ onLoadEndRef.current && onLoadEndRef.current();
61
129
  return isNewVersion
62
130
  ? module.default({
63
131
  // 组件引用
64
132
  ref: componentRef,
65
- // 将依赖穿透下去,用于在组件内部使用依赖(以支持云组件嵌套云组件)
66
- $$dependencies: dependencies
133
+ // 将依赖项穿透下去,用于在组件内部使用依赖项(支持云组件嵌套云组件)
134
+ $$dependencies: stableDependencies
67
135
  })
68
136
  : module.default;
69
137
  });
70
138
  } catch (error) {
71
139
  console.error('云组件加载失败:', error);
72
- onLoadEnd && onLoadEnd();
140
+ onLoadEndRef.current && onLoadEndRef.current();
73
141
  // 可以设置一个错误组件或显示错误信息
74
142
  setComponent(() => () => React.createElement('div', {
75
143
  style: { color: 'red', padding: '10px' }
@@ -83,17 +151,25 @@ export default function CloudComponent(props) {
83
151
  if (styleId) {
84
152
  useUnMountCloudComponentStyle(styleId);
85
153
  }
86
- onDestroy && onDestroy();
154
+ onDestroyRef.current && onDestroyRef.current();
87
155
  };
88
- }, [from, cache, headers, dependencies]);
156
+ }, [from, cache, headers, shouldReloadDependencies]);
157
+
158
+ // 使用 useMemo 来稳定化 componentProps,避免因对象重新创建导致的重新渲染
159
+ const stableComponentProps = React.useMemo(() => {
160
+ return {
161
+ detail: { componentKey },
162
+ ...jjbCommonLib.tools.toObject(componentProps)
163
+ };
164
+ }, [componentKey, JSON.stringify(componentProps)]);
165
+
166
+ // 使用 useMemo 来稳定化 initialize 函数
167
+ const stableInitialize = React.useMemo(() => initialize, [initialize]);
89
168
 
90
169
  return Component && (
91
170
  <Component
92
- initialize={initialize}
93
- {...{
94
- detail: { componentKey },
95
- ...tools.toObject(componentProps)
96
- }}
171
+ initialize={stableInitialize}
172
+ {...stableComponentProps}
97
173
  onMounted={onMounted}
98
174
  onUpdated={onUpdated}
99
175
  />
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cqsjjb/jjb-cloud-component",
3
- "version": "0.0.7-experimental.3",
3
+ "version": "0.0.8",
4
4
  "description": "前端-云组件",
5
5
  "main": "index.js",
6
6
  "scripts": {