Event handler being reattached/recreated every new component render #1287
-
I cannot figure this one out, so of course I'm finally turning here for help. I am running into an issue where the Below are the files to reproduce this minimal example. Any idea what's going on here? Is this a shortcoming of the way the Map component was designed? // example.js
import React from "https://esm.sh/[email protected]"
import ReactDOM from "https://esm.sh/[email protected]/client"
import Map from "https://esm.sh/@planet/[email protected]/[email protected],[email protected],[email protected]";
export {Map};
import View from "https://esm.sh/@planet/[email protected]/[email protected],[email protected],[email protected]";
export {View};
loadCSS("https://esm.sh/[email protected]/ol.css");
function loadCSS(href) {
var head = document.getElementsByTagName('head')[0];
if (document.querySelectorAll(`link[href="${href}"]`).length === 0) {
// Creating link element
var style = document.createElement('link');
style.id = href;
style.href = href;
style.type = 'text/css';
style.rel = 'stylesheet';
head.append(style);
}
}
export function bind(node, config) {
const root = ReactDOM.createRoot(node);
return {
create: (component, props, children) =>
React.createElement(component, wrapEventHandlers(props), ...children),
render: (element) => root.render(element),
unmount: () => root.unmount()
};
}
function wrapEventHandlers(props) {
const newProps = Object.assign({}, props);
for (const [key, value] of Object.entries(props)) {
if (typeof value === "function") {
newProps[key] = makeJsonSafeEventHandler(value);
}
}
return newProps;
}
function stringifyToDepth(val, depth, replacer, space) {
depth = isNaN(+depth) ? 1 : depth;
function _build(key, val, depth, o, a) { // (JSON.stringify() has it's own rules, which we respect here by using it for property iteration)
return !val || typeof val != 'object' ? val : (a=Array.isArray(val), JSON.stringify(val, function(k,v){ if (a || depth > 0) { if (replacer) v=replacer(k,v); if (!k) return (a=Array.isArray(v),val=v); !o && (o=a?[]:{}); o[k] = _build(k, v, a?depth:depth-1); } }), o||(a?[]:{}));
}
return JSON.stringify(_build('', val, depth), null, space);
}
function makeJsonSafeEventHandler(oldHandler) {
// Since we can't really know what the event handlers get passed we have to check if
// they are JSON serializable or not. We can allow normal synthetic events to pass
// through since the original handler already knows how to serialize those for us.
return function safeEventHandler() {
var filteredArguments = [];
Array.from(arguments).forEach(function (arg) {
if (typeof arg === "object" && arg.nativeEvent) {
// this is probably a standard React synthetic event
filteredArguments.push(arg);
} else {
filteredArguments.push(JSON.parse(stringifyToDepth(arg, 3, (key, value) => {
if (key === '') return value;
try {
JSON.stringify(value);
return value;
} catch (err) {
return (typeof value === 'object') ? value : undefined;
}
})))
}
});
oldHandler(...Array.from(filteredArguments));
};
} # app.py
from reactpy import component, html, run, web
module = web.module_from_file(
"example", "example.js",
)
Map, View = web.export(module, ["Map", "View"])
@component
def App():
test, set_test = reactpy.hooks.use_state(True)
return reactpy.html.div({"style": {"width": "100vw", "height": "100vh"}},
Map({"onClick": lambda _: print("CLICKED!") is None and set_test(not test)},
View({"center": [-100, 40], "zoom": 3.5})
)
)
run(App) |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 6 replies
-
What version of ReactPy are you running? I believe this issue was resolved in the latest alpha releases. |
Beta Was this translation helpful? Give feedback.
-
I was able to reproduce this directly with React(JS), so I've opened up a ticket with the planetlabs/maps project here. |
Beta Was this translation helpful? Give feedback.
I was able to reproduce this directly with React(JS), so I've opened up a ticket with the planetlabs/maps project here.