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

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
  // 缓存
@@ -19,6 +19,9 @@ export function useUnMountCloudComponentStyle(styleId) {
19
19
  /**
20
20
  * @description 云组件
21
21
  * @param props {object} 组件props
22
+ * @param props.dependencies {object} 自定义依赖项,会与默认依赖项合并
23
+ * @note 默认内置依赖项:react, react-dom, @cqsjjb/jjb-common-lib
24
+ * @note 用户自定义依赖项会覆盖同名的默认依赖项
22
25
  */
23
26
  export default function CloudComponent(props) {
24
27
  let styleId;
@@ -27,7 +30,7 @@ export default function CloudComponent(props) {
27
30
  from,
28
31
  cache,
29
32
  headers,
30
- dependencies = [],
33
+ dependencies = {},
31
34
  initialize,
32
35
  componentRef,
33
36
  componentKey,
@@ -39,10 +42,73 @@ export default function CloudComponent(props) {
39
42
  onUpdated
40
43
  } = props;
41
44
 
45
+ // 默认内置依赖项,所有云组件都可以使用
46
+ const defaultDependencies = {
47
+ 'react': require('react'),
48
+ 'react-dom': require('react-dom'),
49
+ '@cqsjjb/jjb-common-lib': require('@cqsjjb/jjb-common-lib')
50
+ };
51
+
52
+ // 合并默认依赖和用户自定义依赖,用户依赖优先级更高
53
+ const mergedDependencies = React.useMemo(() => {
54
+ return {
55
+ ...defaultDependencies,
56
+ ...dependencies
57
+ };
58
+ }, [dependencies]);
59
+
60
+ // 使用 useMemo 来稳定化 mergedDependencies 引用,避免不必要的重新渲染
61
+ const stableDependencies = React.useMemo(() => {
62
+ return mergedDependencies;
63
+ }, [mergedDependencies]);
64
+
65
+ // 使用 useRef 来跟踪 dependencies 的变化,避免因对象引用变化导致的重新渲染
66
+ const prevDependenciesRef = React.useRef();
67
+ const shouldReloadDependencies = React.useMemo(() => {
68
+ if (!prevDependenciesRef.current) {
69
+ prevDependenciesRef.current = mergedDependencies;
70
+ return true;
71
+ }
72
+
73
+ // 比较 dependencies 的键和值
74
+ const prevKeys = Object.keys(prevDependenciesRef.current);
75
+ const currentKeys = Object.keys(mergedDependencies);
76
+
77
+ if (prevKeys.length !== currentKeys.length) {
78
+ prevDependenciesRef.current = mergedDependencies;
79
+ return true;
80
+ }
81
+
82
+ for (const key of currentKeys) {
83
+ if (prevDependenciesRef.current[key] !== mergedDependencies[key]) {
84
+ prevDependenciesRef.current = mergedDependencies;
85
+ return true;
86
+ }
87
+ }
88
+
89
+ return false;
90
+ }, [mergedDependencies]);
91
+
92
+ // 使用 useRef 来存储回调函数,避免因回调函数重新创建导致的重新渲染
93
+ const onLoadStartRef = React.useRef(onLoadStart);
94
+ const onLoadEndRef = React.useRef(onLoadEnd);
95
+ const onDestroyRef = React.useRef(onDestroy);
96
+
42
97
  React.useEffect(() => {
98
+ onLoadStartRef.current = onLoadStart;
99
+ onLoadEndRef.current = onLoadEnd;
100
+ onDestroyRef.current = onDestroy;
101
+ });
102
+
103
+ React.useEffect(() => {
104
+ // 只有当 dependencies 真正发生变化时才重新加载
105
+ if (!shouldReloadDependencies && prevDependenciesRef.current) {
106
+ return;
107
+ }
108
+
43
109
  async function load() {
44
110
  try {
45
- onLoadStart && onLoadStart();
111
+ onLoadStartRef.current && onLoadStartRef.current();
46
112
  const {
47
113
  module,
48
114
  styleId: _styleId,
@@ -51,25 +117,25 @@ export default function CloudComponent(props) {
51
117
  from,
52
118
  cache,
53
119
  headers,
54
- dependencies
120
+ dependencies: stableDependencies
55
121
  });
56
122
 
57
123
  styleId = _styleId;
58
124
 
59
125
  setComponent(() => {
60
- onLoadEnd && onLoadEnd();
126
+ onLoadEndRef.current && onLoadEndRef.current();
61
127
  return isNewVersion
62
128
  ? module.default({
63
129
  // 组件引用
64
130
  ref: componentRef,
65
- // 将依赖穿透下去,用于在组件内部使用依赖(以支持云组件嵌套云组件)
66
- $$dependencies: dependencies
131
+ // 将依赖项穿透下去,用于在组件内部使用依赖项(支持云组件嵌套云组件)
132
+ $$dependencies: stableDependencies
67
133
  })
68
134
  : module.default;
69
135
  });
70
136
  } catch (error) {
71
137
  console.error('云组件加载失败:', error);
72
- onLoadEnd && onLoadEnd();
138
+ onLoadEndRef.current && onLoadEndRef.current();
73
139
  // 可以设置一个错误组件或显示错误信息
74
140
  setComponent(() => () => React.createElement('div', {
75
141
  style: { color: 'red', padding: '10px' }
@@ -83,17 +149,25 @@ export default function CloudComponent(props) {
83
149
  if (styleId) {
84
150
  useUnMountCloudComponentStyle(styleId);
85
151
  }
86
- onDestroy && onDestroy();
152
+ onDestroyRef.current && onDestroyRef.current();
87
153
  };
88
- }, [from, cache, headers, dependencies]);
154
+ }, [from, cache, headers, shouldReloadDependencies]);
155
+
156
+ // 使用 useMemo 来稳定化 componentProps,避免因对象重新创建导致的重新渲染
157
+ const stableComponentProps = React.useMemo(() => {
158
+ return {
159
+ detail: { componentKey },
160
+ ...tools.toObject(componentProps)
161
+ };
162
+ }, [componentKey, JSON.stringify(componentProps)]);
163
+
164
+ // 使用 useMemo 来稳定化 initialize 函数
165
+ const stableInitialize = React.useMemo(() => initialize, [initialize]);
89
166
 
90
167
  return Component && (
91
168
  <Component
92
- initialize={initialize}
93
- {...{
94
- detail: { componentKey },
95
- ...tools.toObject(componentProps)
96
- }}
169
+ initialize={stableInitialize}
170
+ {...stableComponentProps}
97
171
  onMounted={onMounted}
98
172
  onUpdated={onUpdated}
99
173
  />
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.7",
4
4
  "description": "前端-云组件",
5
5
  "main": "index.js",
6
6
  "scripts": {