浏览代码

[REF-3203] Find a DOM event-like object in addEvents (#3706)

Masen Furer 9 月之前
父节点
当前提交
06833f6d8d

+ 6 - 1
reflex/.templates/web/utils/state.js

@@ -647,7 +647,12 @@ export const useEventLoop = (
   const [connectErrors, setConnectErrors] = useState([]);
 
   // Function to add new events to the event queue.
-  const addEvents = (events, _e, event_actions) => {
+  const addEvents = (events, args, event_actions) => {
+    if (!(args instanceof Array)) {
+      args = [args];
+    }
+    const _e = args.filter((o) => o?.preventDefault !== undefined)[0]
+
     if (event_actions?.preventDefault && _e?.preventDefault) {
       _e.preventDefault();
     }

+ 5 - 4
reflex/utils/format.py

@@ -438,15 +438,16 @@ def format_prop(
             sig = inspect.signature(prop.args_spec)  # type: ignore
             if sig.parameters:
                 arg_def = ",".join(f"_{p}" for p in sig.parameters)
-                arg_def = f"({arg_def})"
+                arg_def_expr = f"[{arg_def}]"
             else:
                 # add a default argument for addEvents if none were specified in prop.args_spec
                 # used to trigger the preventDefault() on the event.
-                arg_def = "(_e)"
+                arg_def = "...args"
+                arg_def_expr = "args"
 
             chain = ",".join([format_event(event) for event in prop.events])
-            event = f"addEvents([{chain}], {arg_def}, {json_dumps(prop.event_actions)})"
-            prop = f"{arg_def} => {event}"
+            event = f"addEvents([{chain}], {arg_def_expr}, {json_dumps(prop.event_actions)})"
+            prop = f"({arg_def}) => {event}"
 
         # Handle other types.
         elif isinstance(prop, str):

+ 3 - 3
tests/components/base/test_script.py

@@ -58,14 +58,14 @@ def test_script_event_handler():
     )
     render_dict = component.render()
     assert (
-        f'onReady={{(_e) => addEvents([Event("{EvState.get_full_name()}.on_ready", {{}})], (_e), {{}})}}'
+        f'onReady={{(...args) => addEvents([Event("{EvState.get_full_name()}.on_ready", {{}})], args, {{}})}}'
         in render_dict["props"]
     )
     assert (
-        f'onLoad={{(_e) => addEvents([Event("{EvState.get_full_name()}.on_load", {{}})], (_e), {{}})}}'
+        f'onLoad={{(...args) => addEvents([Event("{EvState.get_full_name()}.on_load", {{}})], args, {{}})}}'
         in render_dict["props"]
     )
     assert (
-        f'onError={{(_e) => addEvents([Event("{EvState.get_full_name()}.on_error", {{}})], (_e), {{}})}}'
+        f'onError={{(...args) => addEvents([Event("{EvState.get_full_name()}.on_error", {{}})], args, {{}})}}'
         in render_dict["props"]
     )

+ 1 - 1
tests/components/test_component.py

@@ -826,7 +826,7 @@ def test_component_event_trigger_arbitrary_args():
     assert comp.render()["props"][0] == (
         "onFoo={(__e,_alpha,_bravo,_charlie) => addEvents("
         f'[Event("{C1State.get_full_name()}.mock_handler", {{_e:__e.target.value,_bravo:_bravo["nested"],_charlie:((_charlie.custom) + (42))}})], '
-        "(__e,_alpha,_bravo,_charlie), {})}"
+        "[__e,_alpha,_bravo,_charlie], {})}"
     )
 
 

+ 5 - 5
tests/utils/test_format.py

@@ -477,7 +477,7 @@ def test_format_match(
                 events=[EventSpec(handler=EventHandler(fn=mock_event))],
                 args_spec=lambda: [],
             ),
-            '{(_e) => addEvents([Event("mock_event", {})], (_e), {})}',
+            '{(...args) => addEvents([Event("mock_event", {})], args, {})}',
         ),
         (
             EventChain(
@@ -495,9 +495,9 @@ def test_format_match(
                         ),
                     )
                 ],
-                args_spec=lambda: [],
+                args_spec=lambda e: [e.target.value],
             ),
-            '{(_e) => addEvents([Event("mock_event", {arg:_e.target.value})], (_e), {})}',
+            '{(_e) => addEvents([Event("mock_event", {arg:_e.target.value})], [_e], {})}',
         ),
         (
             EventChain(
@@ -505,7 +505,7 @@ def test_format_match(
                 args_spec=lambda: [],
                 event_actions={"stopPropagation": True},
             ),
-            '{(_e) => addEvents([Event("mock_event", {})], (_e), {"stopPropagation": true})}',
+            '{(...args) => addEvents([Event("mock_event", {})], args, {"stopPropagation": true})}',
         ),
         (
             EventChain(
@@ -513,7 +513,7 @@ def test_format_match(
                 args_spec=lambda: [],
                 event_actions={"preventDefault": True},
             ),
-            '{(_e) => addEvents([Event("mock_event", {})], (_e), {"preventDefault": true})}',
+            '{(...args) => addEvents([Event("mock_event", {})], args, {"preventDefault": true})}',
         ),
         ({"a": "red", "b": "blue"}, '{{"a": "red", "b": "blue"}}'),
         (BaseVar(_var_name="var", _var_type="int"), "{var}"),