@@ -215,27 +215,50 @@ def _render_model_attributes(
215215 h = attrs .pop (k )
216216 handlers_by_event [k ] = h
217217
218- handlers_by_target : Dict [str , EventHandler ] = {}
219- model_event_targets : Dict [str , _ModelEventTarget ] = {}
218+ if old_state is None :
219+ self ._render_model_event_handlers_without_old_state (
220+ new_state , handlers_by_event
221+ )
222+ return None
223+
224+ for old_event in set (old_state .targets_by_event ).difference (handlers_by_event ):
225+ old_target = old_state .targets_by_event [old_event ]
226+ del self ._event_handlers [old_target ]
227+
228+ if not handlers_by_event :
229+ return None
230+
231+ model_event_handlers = new_state .model ["eventHandlers" ] = {}
220232 for event , handler in handlers_by_event .items ():
221- target = f"{ new_state .key_path } /{ event } "
222- handlers_by_target [target ] = handler
223- model_event_targets [event ] = {
233+ target = old_state .targets_by_event .get (event , id (handler ))
234+ new_state .targets_by_event [event ] = target
235+ self ._event_handlers [target ] = handler
236+ model_event_handlers [event ] = {
224237 "target" : target ,
225238 "preventDefault" : handler .prevent_default ,
226239 "stopPropagation" : handler .stop_propagation ,
227240 }
228241
229- if old_state is not None :
230- for old_target in set (old_state .event_targets ).difference (
231- handlers_by_target
232- ):
233- del self ._event_handlers [old_target ]
242+ return None
243+
244+ def _render_model_event_handlers_without_old_state (
245+ self ,
246+ new_state : _ModelState ,
247+ handlers_by_event : Dict [str , EventHandler ],
248+ ) -> None :
249+ if not handlers_by_event :
250+ return None
234251
235- if model_event_targets :
236- new_state .event_targets .update (handlers_by_target )
237- self ._event_handlers .update (handlers_by_target )
238- new_state .model ["eventHandlers" ] = model_event_targets
252+ model_event_handlers = new_state .model ["eventHandlers" ] = {}
253+ for event , handler in handlers_by_event .items ():
254+ target = hex (id (handler ))[2 :]
255+ new_state .targets_by_event [event ] = target
256+ self ._event_handlers [target ] = handler
257+ model_event_handlers [event ] = {
258+ "target" : target ,
259+ "preventDefault" : handler .prevent_default ,
260+ "stopPropagation" : handler .stop_propagation ,
261+ }
239262
240263 return None
241264
@@ -283,8 +306,9 @@ def _render_model_children(
283306 self ._unmount_model_states (list (old_child_states .values ()))
284307
285308 new_children = new_state .model ["children" ] = []
286- for index , (key , (child_type , child )) in enumerate (
287- raw_typed_children_by_key .items ()
309+ for index , (key , (child_type , child )) in (
310+ # we can enumerate this because dict insertion order is preserved
311+ enumerate (raw_typed_children_by_key .items ())
288312 ):
289313 if child_type is DICT_TYPE :
290314 old_child_state = old_state .children_by_key .get (key )
@@ -348,9 +372,8 @@ class _ModelState:
348372 "life_cycle_hook" ,
349373 "component" ,
350374 "patch_path" ,
351- "key_path" ,
352375 "model" ,
353- "event_targets " ,
376+ "targets_by_event " ,
354377 "children_by_key" ,
355378 "__weakref__" ,
356379 )
@@ -369,16 +392,15 @@ def __init__(
369392
370393 if parent is not None :
371394 self ._parent_ref = ref (parent )
372- self .key_path = f"{ parent .key_path } /{ key } "
373395 self .patch_path = f"{ parent .patch_path } /children/{ index } "
374396 else :
375- self .key_path = self . patch_path = ""
397+ self .patch_path = ""
376398
377399 if life_cycle_hook is not None :
378400 self .life_cycle_hook = life_cycle_hook
379401 self .component = life_cycle_hook .component
380402
381- self .event_targets : Set [str ] = set ()
403+ self .targets_by_event : Dict [str , str ] = {}
382404 self .children_by_key : Dict [str , _ModelState ] = {}
383405
384406 @property
0 commit comments