[지붕재] select 폴링 stale closure 수정 — 데이터 도착 즉시 종료 + 매칭 0건 에러 안내
Co-Authored-By: Claude Opus 4 <noreply@anthropic.com>
This commit is contained in:
parent
b031e703ec
commit
d0c3110801
@ -1,4 +1,4 @@
|
|||||||
import { useContext, useEffect, useState } from 'react'
|
import { useContext, useEffect, useRef, useState } from 'react'
|
||||||
import { useRecoilState, useRecoilValue, useResetRecoilState, useSetRecoilState } from 'recoil'
|
import { useRecoilState, useRecoilValue, useResetRecoilState, useSetRecoilState } from 'recoil'
|
||||||
import {
|
import {
|
||||||
adsorptionPointModeState,
|
adsorptionPointModeState,
|
||||||
@ -119,6 +119,12 @@ export function useCanvasSetting(executeEffect = true) {
|
|||||||
const [basicSetting, setBasicSettings] = useRecoilState(basicSettingState)
|
const [basicSetting, setBasicSettings] = useRecoilState(basicSettingState)
|
||||||
const { getRoofMaterialList, getModuleTypeItemList } = useMasterController()
|
const { getRoofMaterialList, getModuleTypeItemList } = useMasterController()
|
||||||
const [roofMaterials, setRoofMaterials] = useRecoilState(roofMaterialsAtom)
|
const [roofMaterials, setRoofMaterials] = useRecoilState(roofMaterialsAtom)
|
||||||
|
// [ROOFMAT-POLL-FIX 2026-06-29] fetchBasicSettings 의 폴링 루프가 stale closure 에 묶여
|
||||||
|
// Header.jsx 가 채운 최신 roofMaterials 를 못 읽던 문제 → ref 미러로 최신값을 읽어 데이터 도착 즉시 종료.
|
||||||
|
const roofMaterialsRef = useRef(roofMaterials)
|
||||||
|
useEffect(() => {
|
||||||
|
roofMaterialsRef.current = roofMaterials
|
||||||
|
}, [roofMaterials])
|
||||||
const [addedRoofs, setAddedRoofs] = useRecoilState(addedRoofsState)
|
const [addedRoofs, setAddedRoofs] = useRecoilState(addedRoofsState)
|
||||||
const setCurrentMenu = useSetRecoilState(currentMenuState)
|
const setCurrentMenu = useSetRecoilState(currentMenuState)
|
||||||
|
|
||||||
@ -321,20 +327,22 @@ export function useCanvasSetting(executeEffect = true) {
|
|||||||
const targetObjectNo = objectNo || correntObjectNo
|
const targetObjectNo = objectNo || correntObjectNo
|
||||||
|
|
||||||
// 지붕재 데이터가 없으면 Header.jsx에서 로드될 때까지 기다림
|
// 지붕재 데이터가 없으면 Header.jsx에서 로드될 때까지 기다림
|
||||||
let materials = roofMaterials
|
// [ROOFMAT-POLL-FIX 2026-06-29] roofMaterialsRef 로 최신값을 폴링 → 데이터가 들어오는 즉시 종료.
|
||||||
|
// (이전엔 stale closure 로 항상 풀카운트를 소모해 select 가 늦게 떴음)
|
||||||
|
let materials = roofMaterialsRef.current
|
||||||
if (!materials || materials.length === 0) {
|
if (!materials || materials.length === 0) {
|
||||||
logger.log('Waiting for roofMaterials to be loaded from Header.jsx...')
|
logger.log('Waiting for roofMaterials to be loaded from Header.jsx...')
|
||||||
// 최대 2초간 기다림 (20번 × 100ms)
|
// 최대 1초간 기다림 (10번 × 100ms), 데이터 도착 시 즉시 break
|
||||||
let waitCount = 0
|
let waitCount = 0
|
||||||
while ((!materials || materials.length === 0) && waitCount < 20) {
|
while ((!materials || materials.length === 0) && waitCount < 10) {
|
||||||
await new Promise(resolve => setTimeout(resolve, 100))
|
await new Promise((resolve) => setTimeout(resolve, 100))
|
||||||
materials = roofMaterials
|
materials = roofMaterialsRef.current
|
||||||
waitCount++
|
waitCount++
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!materials || materials.length === 0) {
|
if (!materials || materials.length === 0) {
|
||||||
logger.log('roofMaterials still not loaded after 2 seconds, proceeding without them')
|
logger.log('roofMaterials still not loaded after 1 second, proceeding via fallback')
|
||||||
// 비상시에만 addRoofMaterials 호출 (fallback)
|
// 10회 안에 못 받으면 fallback 직접 호출 (getRoofMaterialList promise cache 로 중복 네트워크 방지)
|
||||||
materials = await addRoofMaterials()
|
materials = await addRoofMaterials()
|
||||||
logger.log('roofMaterials loaded via fallback:', materials)
|
logger.log('roofMaterials loaded via fallback:', materials)
|
||||||
} else {
|
} else {
|
||||||
@ -485,6 +493,15 @@ export function useCanvasSetting(executeEffect = true) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// [ROOFMAT-TOPMENU-DIAG 2026-06-29] 저장 roofMatlCd 가 마스터에 없거나 마스터 미로드로 매칭 0건 →
|
||||||
|
// top 메뉴 지붕재 select(CanvasMenu.jsx:648)가 렌더되지 않으므로 사용자에게 에러 안내.
|
||||||
|
logger.warn('[ROOFMAT-TOPMENU-DIAG] addRoofs 0건 — select 미표시', {
|
||||||
|
objectNo: targetObjectNo,
|
||||||
|
materialsCount: materials?.length ?? 0,
|
||||||
|
savedRoofCodes: roofsArray.map((r) => r.roofMatlCd),
|
||||||
|
})
|
||||||
|
swalFire({ icon: 'error', text: getMessage('canvas.roof.material.not.found') })
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
@ -60,6 +60,7 @@
|
|||||||
"modal.placement.initial.setting.roof.angle": "角度",
|
"modal.placement.initial.setting.roof.angle": "角度",
|
||||||
"modal.placement.initial.setting.roof.material": "屋根材選択(単位mm)",
|
"modal.placement.initial.setting.roof.material": "屋根材選択(単位mm)",
|
||||||
"modal.placement.initial.setting.roof.material.info": "対応可能な屋根材や足場は限定されますので、必ず事前マニュアルをご確認ください。",
|
"modal.placement.initial.setting.roof.material.info": "対応可能な屋根材や足場は限定されますので、必ず事前マニュアルをご確認ください。",
|
||||||
|
"canvas.roof.material.not.found": "屋根材情報を読み込めませんでした。ページを再読み込みするか、屋根材設定をご確認ください。",
|
||||||
"modal.placement.initial.setting.rafter": "垂木",
|
"modal.placement.initial.setting.rafter": "垂木",
|
||||||
"modal.roof.shape.setting": "屋根形状の設定",
|
"modal.roof.shape.setting": "屋根形状の設定",
|
||||||
"modal.roof.shape.setting.ridge": "棟",
|
"modal.roof.shape.setting.ridge": "棟",
|
||||||
|
|||||||
@ -60,6 +60,7 @@
|
|||||||
"modal.placement.initial.setting.roof.angle": "각도",
|
"modal.placement.initial.setting.roof.angle": "각도",
|
||||||
"modal.placement.initial.setting.roof.material": "지붕재 선택(단위mm)",
|
"modal.placement.initial.setting.roof.material": "지붕재 선택(단위mm)",
|
||||||
"modal.placement.initial.setting.roof.material.info": "대응 가능한 지붕재 및 발판은 한정되므로 반드시 사전 매뉴얼을 확인하십시오.",
|
"modal.placement.initial.setting.roof.material.info": "대응 가능한 지붕재 및 발판은 한정되므로 반드시 사전 매뉴얼을 확인하십시오.",
|
||||||
|
"canvas.roof.material.not.found": "지붕재 정보를 불러오지 못했습니다. 페이지를 새로고침하거나 지붕재 설정을 확인해 주세요.",
|
||||||
"modal.placement.initial.setting.rafter": "서까래",
|
"modal.placement.initial.setting.rafter": "서까래",
|
||||||
"modal.roof.shape.setting": "지붕형상 설정",
|
"modal.roof.shape.setting": "지붕형상 설정",
|
||||||
"modal.roof.shape.setting.ridge": "용마루",
|
"modal.roof.shape.setting.ridge": "용마루",
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user