11import { PanelBaseLayout } from './base/PanelBaseLayout' ;
2- import { useCurNodes , useSelectNode , useSelectedNodeId , useDeleteNode , useAddNode } from '../../../../stores/useEditorStore' ;
2+ import { useSelectNode , useSelectedNodeId , useDeleteNode , useAddNode , useChildrenMap , useNodeMap } from '../../../../stores/useEditorStore' ;
33import { COMPONENT_DEFAULTS } from '../../../../shared/lib/component-defaults' ;
44import { cn } from '@repo/utils' ;
55import {
@@ -37,19 +37,18 @@ const NODE_TYPE_ICONS: Record<string, LucideIcon> = {
3737
3838interface LayerItemProps {
3939 node : WcxNode ;
40- nodes : WcxNode [ ] ;
40+ childrenMap : Record < string , WcxNode [ ] > ;
4141 selectedId : string | null ;
4242 onSelect : ( id : string ) => void ;
4343 onContextMenu : ( e : React . MouseEvent , nodeId : string ) => void ;
4444 depth : number ;
4545}
4646
47- const LayerItem = ( { node, nodes , selectedId, onSelect, onContextMenu, depth } : LayerItemProps ) => {
47+ const LayerItem = ( { node, childrenMap , selectedId, onSelect, onContextMenu, depth } : LayerItemProps ) => {
4848 const [ isExpanded , setIsExpanded ] = useState ( true ) ;
4949
50- const children = nodes
51- . filter ( ( n ) => n . parent_id === node . id )
52- . sort ( ( a , b ) => a . position - b . position ) ;
50+ // childrenMap에서 O(1) 조회 (filter+sort 제거)
51+ const children = childrenMap [ node . id ] || [ ] ;
5352
5453 const hasChildren = children . length > 0 ;
5554 const isSelected = selectedId === node . id ;
@@ -117,7 +116,7 @@ const LayerItem = ({ node, nodes, selectedId, onSelect, onContextMenu, depth }:
117116 < LayerItem
118117 key = { child . id }
119118 node = { child }
120- nodes = { nodes }
119+ childrenMap = { childrenMap }
121120 selectedId = { selectedId }
122121 onSelect = { onSelect }
123122 onContextMenu = { onContextMenu }
@@ -133,7 +132,8 @@ const LayerItem = ({ node, nodes, selectedId, onSelect, onContextMenu, depth }:
133132/* ─────────────────────── Layer Panel ─────────────────────── */
134133
135134export const LayerPanel = ( ) => {
136- const nodes = useCurNodes ( ) || [ ] ;
135+ const nodeMap = useNodeMap ( ) ;
136+ const childrenMap = useChildrenMap ( ) ;
137137 const selectedId = useSelectedNodeId ( ) ;
138138 const selectNode = useSelectNode ( ) ;
139139 const deleteNode = useDeleteNode ( ) ;
@@ -150,7 +150,8 @@ export const LayerPanel = () => {
150150 const handleContextMenu = ( e : React . MouseEvent , nodeId : string ) => {
151151 e . preventDefault ( ) ;
152152 e . stopPropagation ( ) ;
153- const targetNode = nodes . find ( ( n ) => n . id === nodeId ) ;
153+ // nodeMap에서 O(1) 조회
154+ const targetNode = nodeMap [ nodeId ] ;
154155 if ( ! targetNode ) return ;
155156 setContextMenu ( { x : e . clientX , y : e . clientY , nodeId, nodeType : targetNode . type } ) ;
156157 } ;
@@ -161,8 +162,9 @@ export const LayerPanel = () => {
161162 const defaults = COMPONENT_DEFAULTS [ type ] ;
162163 if ( ! defaults ) return ;
163164
164- const siblingCount = nodes . filter ( ( n ) => n . parent_id === parentId ) . length ;
165- const parentNode = nodes . find ( ( n ) => n . id === parentId ) ;
165+ // childrenMap에서 형제 수 조회
166+ const siblingCount = ( childrenMap [ parentId ] || [ ] ) . length ;
167+ const parentNode = nodeMap [ parentId ] ;
166168
167169 const newNode : WcxNode = {
168170 id : `${ type . toLowerCase ( ) } -${ Date . now ( ) } ` ,
@@ -181,12 +183,11 @@ export const LayerPanel = () => {
181183
182184 addNode ( newNode ) ;
183185 } ,
184- [ nodes , addNode ] ,
186+ [ childrenMap , nodeMap , addNode ] ,
185187 ) ;
186188
187- const rootNodes = nodes
188- . filter ( ( node ) => node . parent_id === null )
189- . sort ( ( a , b ) => a . position - b . position ) ;
189+ // 루트 노드: childrenMap["__root__"]에서 바로 조회 (이미 정렬됨)
190+ const rootNodes = childrenMap [ "__root__" ] || [ ] ;
190191
191192 return (
192193 < PanelBaseLayout title = "레이어" description = "페이지 구성 요소 계층" >
@@ -196,7 +197,7 @@ export const LayerPanel = () => {
196197 < LayerItem
197198 key = { node . id }
198199 node = { node }
199- nodes = { nodes }
200+ childrenMap = { childrenMap }
200201 selectedId = { selectedId }
201202 onSelect = { selectNode }
202203 onContextMenu = { handleContextMenu }
0 commit comments