Say that you design a component X in Dash with a component property foo. If you try to pass any other property, say bar, from Dash, you’ll get an error,
TypeError: The `X` component (version 1.0.0) with the ID "some_id" received an unexpected keyword argument: `bar`
On the react side, properties are updated via the setProps function. I noticed that you can call this function using any property name. Hence, if add code like,
props.setProps({bar: "hello world!"})
I don’t see any errors. Furthermore, if I add a callback that listens for bar,
@calllback(Input("some_id", "bar", ...)
it works perfectly. Now my question is - is this a bug or a feature? I am asking because I am considering using this functionality (i.e. the ability to dynamically add properties) as part of a Dash component design. Maybe @alexcjohnson knows?
I definitely wouldn’t recommend doing this, and it’s conceivable we would close this loophole at some point. That said there’s a fully-supported feature you CAN use to do things like this, wildcard properties. If you add data-* or aria-* to propTypes that we’ll allow any props matching those patterns. The only place I’m aware of this being used right now is in html, for data- and aria- props - that’s why we built this feature, to cover important pieces of the HTML spec for these low-level components, but it’s available for other components to use. If data-* and aria-* are too restrictive for your use case it would be easy to adjust the logic to make the prefix flexible. In particular there’s no reason it needs to have the - which makes it hard to use from the Python side.
@alexcjohnson Thank you for the enlightenment . This was exactly the kind of information I was looking for. I think it would be a great feature to allow wildcards properties in general. In my current use case (events) that would work nicely (e.g. allowing *event props), and I imagine this feature could be relevant in the future also when other larger components are wrapped for Dash
aria-* and data-* aren’t going away for html components, and for other components it’s up to the component author to add those where appropriate, shouldn’t generally need to accept wildcards once there’s a definite purpose for the component but if you do need it you can just make a component that’s an object that accepts arbitrary keys inside it, and forward those keys along as separate attributes to the DOM.
FWIW elsewhere in Dash, if the underlying trigger is an event we typically represent the prop as <eventName>Data - like relayoutData and such in dcc.Graph. So it wouldn’t be too big a stretch to use data-* for this purpose. But yeah if the feature were generalized to anything* we could also include *anything
I tried out the data-* props approach, but I didn’t like it - mainly due to the dash operator being a hassle to use in JavaScipt for object keys, which will make it more tedius for people to write custom event handlers. Instead, I have decided to go with *Data (e.g. clickData), which is also more coherent with other Dash components as you noted. The main downside is that these properties are currently not supported, i.e. I’ll have to rely on the “hack” until official support is available. @alexcjohnson is there anything I can do to speed up that process, i.e. filing a bug report/feature requet/PR etc.?
@Emil A PR probably wouldn’t be too hard, if you’re up for it. Would just need some changes in _py_components_generation.py and base_component.py, being careful that any update is backward-compatible with all the other components out there, and that any component using the new feature requires a version of Dash that supports it.
Interestingly the issue of unexpected props in React is pretty general - see eg Check for extraneous props in React (and save hours of debugging) - DEV Community where they talk about prop-types-exact among other options. I suspect prop-types-exact itself gives too hard a failure to be a good fit for Dash, but if we do want to harmonize the front and back-end behavior we should be able to amend checkPropTypes.js to look for unexpected props. I don’t think this routine is currently testing the types of wildcard props at all, so we’d need to sort that out at the same time so that wildcard props didn’t appear as extraneous.