@nine-lab/nine-mu 0.1.387 → 0.1.389
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.
- package/dist/nine-mu.js +21 -14
- package/dist/nine-mu.js.map +1 -1
- package/dist/nine-mu.umd.js +1 -1
- package/dist/nine-mu.umd.js.map +1 -1
- package/package.json +1 -1
- package/src/components/hook/NineHook.js +25 -23
package/package.json
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
|
-
import React, { createContext,
|
|
1
|
+
import React, { createContext, useState, useContext, lazy, Suspense, useEffect } from 'react';
|
|
2
2
|
import { Route, Routes } from 'react-router-dom';
|
|
3
3
|
|
|
4
4
|
// ==========================================
|
|
5
|
-
// 1. 내부 기능 A: ScreenContext 및
|
|
5
|
+
// 1. 내부 기능 A: ScreenContext 및 전역 공급자 (수출형)
|
|
6
6
|
// ==========================================
|
|
7
7
|
const ScreenContext = createContext();
|
|
8
8
|
export const useScreen = () => useContext(ScreenContext);
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
// 🎯 기존 ScreenProvider를 이름 변경 및 전역 동적 데이터 바인딩 셋업
|
|
11
|
+
export const NineScreenProvider = ({ children }) => {
|
|
11
12
|
const [activeView, setActiveView] = useState('list-wrapper');
|
|
12
13
|
const [selectedData, setSelectedData] = useState(null);
|
|
14
|
+
const [menuData, setMenuData] = useState([]); // 💡 데이터 통신 허브를 여기로 단일화
|
|
13
15
|
|
|
14
16
|
const goto = (selector, data) => {
|
|
15
17
|
setActiveView(selector);
|
|
@@ -18,7 +20,7 @@ const ScreenProvider = ({ children }) => {
|
|
|
18
20
|
|
|
19
21
|
return React.createElement(
|
|
20
22
|
ScreenContext.Provider,
|
|
21
|
-
{ value: { activeView, selectedData, goto } },
|
|
23
|
+
{ value: { activeView, selectedData, goto, menuData, setMenuData } }, // 🎯 데이터 변경 권한까지 자식들에게 공유
|
|
22
24
|
children
|
|
23
25
|
);
|
|
24
26
|
};
|
|
@@ -33,14 +35,9 @@ const Default404 = () => {
|
|
|
33
35
|
};
|
|
34
36
|
|
|
35
37
|
const createDynamicRoutes = (menuData, projectViews, Custom404) => {
|
|
36
|
-
// 기본 404 및 홈 설정
|
|
37
38
|
const lazyLoad = (viewPath) => {
|
|
38
39
|
const importer = projectViews[viewPath];
|
|
39
|
-
|
|
40
|
-
// 🎯 [404 해결 포인트] 사용자가 등록한 404가 있으면 그걸 쓰고, 없으면 기본 내장 404를 띄웁니다.
|
|
41
|
-
if (!importer) {
|
|
42
|
-
return Custom404 ? Custom404 : Default404;
|
|
43
|
-
}
|
|
40
|
+
if (!importer) return Custom404 ? Custom404 : Default404;
|
|
44
41
|
return lazy(() => importer());
|
|
45
42
|
};
|
|
46
43
|
|
|
@@ -66,7 +63,6 @@ const createDynamicRoutes = (menuData, projectViews, Custom404) => {
|
|
|
66
63
|
const sanitizedParts = pathParts.map(part => part.replace(/-/g, "_"));
|
|
67
64
|
const fullFolderPath = sanitizedParts.join("/");
|
|
68
65
|
|
|
69
|
-
// 사용자 프로젝트 루트 기준 상대 경로 매핑
|
|
70
66
|
const componentPath = `./views/${fullFolderPath}/${pascalName}.jsx`;
|
|
71
67
|
|
|
72
68
|
dynamicRoutes.push({
|
|
@@ -77,7 +73,6 @@ const createDynamicRoutes = (menuData, projectViews, Custom404) => {
|
|
|
77
73
|
});
|
|
78
74
|
}
|
|
79
75
|
|
|
80
|
-
// 🎯 [404 해결 포인트] 정의되지 않은 모든 주소(*)는 라우터 레벨에서 404 매핑 컴포넌트로 리다이렉트
|
|
81
76
|
dynamicRoutes.push({ path: "*", Component: Custom404 ? Custom404 : Default404 });
|
|
82
77
|
return dynamicRoutes;
|
|
83
78
|
};
|
|
@@ -203,16 +198,16 @@ class NineExceptionHook extends React.Component {
|
|
|
203
198
|
}
|
|
204
199
|
|
|
205
200
|
// ==========================================
|
|
206
|
-
// 🎯 3.
|
|
207
|
-
// ==========================================
|
|
208
|
-
// ==========================================
|
|
209
|
-
// 🎯 3. 최종 완결: 자식 컴포넌트(children)를 수용하는 구조로 변경
|
|
201
|
+
// 🎯 3. 최종 완결: 순수 라우터 및 에러 실드 역할만 수행
|
|
210
202
|
// ==========================================
|
|
211
203
|
export function NineHook({ menuUrl, views, error404, onCatch, fallback, styles, containerStyle }) {
|
|
212
|
-
|
|
204
|
+
// 🎯 상위 최상단 NineScreenProvider가 뿌려주는 주파수 수신
|
|
205
|
+
const context = useContext(ScreenContext);
|
|
206
|
+
const menuData = context ? context.menuData : [];
|
|
207
|
+
const setMenuData = context ? context.setMenuData : null;
|
|
208
|
+
|
|
213
209
|
const [localMenuData, setLocalMenuData] = useState([]);
|
|
214
210
|
|
|
215
|
-
// 부모 컨텍스트가 없을 때를 대비한 안전 장치 및 실시간 fetch
|
|
216
211
|
const fetchRoutes = async () => {
|
|
217
212
|
if (!menuUrl) return;
|
|
218
213
|
try {
|
|
@@ -220,11 +215,18 @@ export function NineHook({ menuUrl, views, error404, onCatch, fallback, styles,
|
|
|
220
215
|
if (response.ok) {
|
|
221
216
|
const data = await response.json();
|
|
222
217
|
|
|
223
|
-
//
|
|
224
|
-
if (
|
|
225
|
-
|
|
218
|
+
// 🎯 상위 Context가 존재하면 거기를 갱신시켜 외부 LeftMenu까지 연쇄 반응 트리거
|
|
219
|
+
if (setMenuData) {
|
|
220
|
+
setMenuData((prev) => {
|
|
221
|
+
if (JSON.stringify(prev) === JSON.stringify(data)) return prev;
|
|
222
|
+
console.log("🔥 [Nine-Library] 최상단 NineScreenProvider 데이터 무선 동기화");
|
|
223
|
+
return data;
|
|
224
|
+
});
|
|
226
225
|
} else {
|
|
227
|
-
setLocalMenuData(
|
|
226
|
+
setLocalMenuData((prev) => {
|
|
227
|
+
if (JSON.stringify(prev) === JSON.stringify(data)) return prev;
|
|
228
|
+
return data;
|
|
229
|
+
});
|
|
228
230
|
}
|
|
229
231
|
}
|
|
230
232
|
} catch (e) {
|
|
@@ -245,7 +247,7 @@ export function NineHook({ menuUrl, views, error404, onCatch, fallback, styles,
|
|
|
245
247
|
};
|
|
246
248
|
}, [menuUrl]);
|
|
247
249
|
|
|
248
|
-
const targetData =
|
|
250
|
+
const targetData = setMenuData ? menuData : localMenuData;
|
|
249
251
|
const dynamicRoutes = createDynamicRoutes(targetData, views, error404);
|
|
250
252
|
|
|
251
253
|
return React.createElement(
|