Skip to main content

AutoField algorithm

Background#

Since the beginning, AutoField was an ordinary React component. Then, in #741, the kind parameter of connectField was introduced to make certain optimizations possible. To be exact, this parameter made it possible to reduce the overhead of AutoField to minimum. The problem is that it increased the complexity of custom themes (or at least keeping them performant).

In #800, a new way of creating AutoField was introduced. Now, instead of a React component, you only specify the component based on its props - the rest is handled in createAutoField.

Default AutoField implementation#

import { createAutoField } from 'uniforms';
const AutoField = createAutoField(props => {
if (props.allowedValues) {
return props.checkboxes && props.fieldType !== Array
? RadioField
: SelectField;
}
switch (props.fieldType) {
case Array:
return ListField;
case Boolean:
return BoolField;
case Date:
return DateField;
case Number:
return NumField;
case Object:
return NestField;
case String:
return TextField;
}
return invariant(false, 'Unsupported field type: %s', props.fieldType);
});

Overriding AutoField#

While specifying the autoField prop on your QuickForm or AutoForm components may cover a lot of cases, some fields - ListField and NestField - use AutoField directly. That means there's no easy way to let them know that you have a custom component defined.

To make it possible, all AutoFields created with the createAutoField are configurable. To adjust the components, use the React context available in AutoField.componentDetectorContext. You can use it as often as needed - in most apps once will be enough. Example:

<AutoField.componentDetectorContext.Provider value={(props, uniforms) => /* ... */}>
<Application />
</AutoField.componentDetectorContext.Provider>

If you want to add an exception and then fallback to the existing algorithm, use AutoField.defaultComponentDetector. Example:

<AutoField.componentDetectorContext.Provider
value={(props, uniforms) => {
if (props.useSpecialField) {
return SpecialField;
}
return AutoField.defaultComponentDetector(props, uniforms);
}}
>
<Application />
</AutoField.componentDetectorContext.Provider>