You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
A uiSchema template override that is a React element or an unregistered name reaches React instead of falling back #5432
I understand that providing a SSCCE example is tremendously useful to the maintainers
I have read the documentation
What theme are you using?
core
Version
7.x (v7 branch)
Current Behavior
getTemplate() in packages/utils/src/getTemplate.ts resolves a template override from the uiSchema (ui:FieldTemplate, ui:ArrayFieldTemplate, ui:ObjectFieldTemplate and the rest) two ways: a string that names a registered template, or anything else that is truthy:
The fallback returns the override without checking that it is a component, so two mistakes reach React. getTemplates() resolves each override through getTemplate(), so it returns the same values. Measured on v7:
uiSchema
getTemplate('FieldTemplate', …) returns
at render
'ui:FieldTemplate': MyTemplate
MyTemplate
renders
'ui:FieldTemplate': 'FieldTemplate' (registered)
the registered template
renders
'ui:FieldTemplate': <MyTemplate /> (an element)
the element
React throws "Element type is invalid"
'ui:FieldTemplate': 'Fieldtemplate' (a typo)
the string 'Fieldtemplate'
rendered as an unknown <fieldtemplate> DOM element, with the template's props as attributes
The typo is the worse of the two: nothing throws, the field's markup is replaced by an unknown element, and the only signal is whatever React logs about unknown props.
Expected Behavior
Fall back to the registry's template when the override is neither a component nor the name of a registered template, and warn through logOnce(), the same way #5363 treats an unusable ui:field and a LayoutGridField cell's render.
#5363 adds isComponentType() to @rjsf/utils, which accepts a function or a memo()/forwardRef()/lazy() component and rejects a React element. The fallback above can use it. ButtonTemplates, the one template that is a map of components rather than a component, already returns early from getTemplate(), so the check doesn't need a special case for it.
Found in review of the #5363 fix and left out of it to keep that change scoped to ui:field, ui:widget and render.
Activity