Pattern-matching not finding components created on React script

TLDR:

How should I define id attributes for elements created directly in React so they are captured by Dash pattern-matching?

Long description:

I’m working on an extension that wraps a React component (Parent) that is responsible to create other components (Children). To be clear: I don’t create Children directly, but indirectly by modifying a prop of Parent.

Parent does not define the id attribute for Children, but I can define the id for customized Children that I import from a separate script. In this script I am trying to create an id following the pattern-matching way, so it could be accessible by Dash callbacks.

It is failing though, this is what Dash shows me at the moment of creation of the component:

A nonexistent object was used in an `Output` of a Dash callback. 
The id of this object is {"index":{"wild":"MATCH"},"type":"node-element-model"} 
with MATCH values [1] and the property is `children`. 
The wildcard ids currently available are logged above.

But the component with this id is created, as shown by elements inspection in the browser:

also in the browsers’ console I can get the right element by id using:

document.getElementById(JSON.stringify({"index":1,"type":"node-element-model"}, Object.keys({"index":1,"type":"node-element-model"}).sort()))

so why is pattern-matching failing here? And what can I try to make it work? Any ideas?

1 Like

Pattern-matching callbacks, indeed all Dash callbacks, operate based on the contents of the app layout, not based on the contents of the DOM. The app layout, by the time the Dash renderer gets it, is simply a JSON structure where each Dash component is an object {namespace, type, props} and props is an object that can contain other Dash component objects (again, simple objects {namespace, type, props}, not React component instances) inside its children attribute. When the layout is mutated (by a callback or by a component calling its setProps prop), the Dash renderer will instantiate the appropriate components by finding window[namespace][type] and passing the given props to them - having first converted any children to Dash components as necessary as well as stringifying pattern-matching IDs.

Unfortunately though, even if you get the object structure correct, right now I don’t think having the component call setProps({children: ...}) will work. We could add support for this, but right now setProps doesn’t trigger us to search for IDs inside children and then trigger the necessary callbacks, the way that callbacks themselves do.

I’m curious though, why involve dash renderer and pattern-matching callbacks at all here? Most complex Dash components keep everything that happens inside them encapsulated - so if you have some complex prop that defines the children of the component then leave it at that; don’t re-expose this as a children prop, just render the internal pieces based on that original prop, and hook up the connections between these children just using regular React patterns inside the main component. Would that work?

2 Likes