As v3 release is getting closer every day, before an actual launch we'll need a written migration guide. The best start would be to collect all changelog entries.
_(this comment will be updated)_
NOTE: This guide is designed to help you through the migration. If you went through it and encountered any problems - do let us know. For more information on _why_ certain changes were made, see the CHANGELOG.md.
NOTE: When migrating to v3, use the newest version. Gradual updates will take more time and won't ease this process.
Validation flow changes
Bridge validators have to return errors instead of throwing them.
// GraphQL Schema
function validator(model) {
if (errors.length) {
- throw { details: validator.errors };
+ return { details: validator.errors };
}
}
// JSON Schema
function createValidator(schema) {
const validator = ajv.compile(schema);
return (model) => {
validator(model);
if (validator.errors && validator.errors.length) {
- throw { details: validator.errors };
+ return { details: validator.errors };
}
};
}
onSubmitSuccess and onSubmitFailure. Perform all needed operations directly in the onSubmit:diff
-onSubmit={onSubmit}
-onSubmitSuccess={onSubmitSuccess}
-onSubmitFailure={onSubmitFailure}
+onSubmit={model => {
<ul>
<li>const result = onSubmit(model);</li>
<li>result.then(onSubmitSuccess, onSubmitFailure);</li>
<li>return result;<br />
+}}`<br />
onValidate is no longer using callbacks. The error (or the lack of it) has to be returned either synchronously or asynchronously (i.e. wrapped in a promise).diff
-onValidate={(error, done) => done(error)}
+onValidate={async error => error}
context, contextTypes, childContextTypes, or getChildContext* methods directly, there's nothing to do.useForm hook (functional components), contextType static property (class components), or <context.Consumer /> (both).context, is exported from the uniforms package.changed, changedMap, submitting, and validating were lifted from the state property to the root.AutoForm.state.modelSync. Use AutoForm.state.model instead.BaseField. Use connectField or useField instead.BaseForm.getChangedKeys. Use changedKeys directly.BaseForm.state.bridge. Use BaseForm.props.schema instead.Bridge.check. Without createSchemaBridge it's no longer needed.baseField from connectField options. There's no one solution here and it may require additional changes, depending on the usage.createSchemaBridge. Now all *Bridge instances have to be created manually.ensureValue from connectField options. That means undefined will no longer be automatically passed to the field as ''. Use value ?? '' instead. This option was enabled by default, therefore it will impact all your custom fields.includeParent from connectField options. Use useField as many times as needed instead.tsx
const parentName = joinName(joinName(null, props.name).slice(0, -1));
const parentField = useField(parentName, {}, { absoluteName: true })[0];
injectName. In most cases, it can be safely omitted.mapProps from connectField options. Map props directly in the component.nothing. Use null instead.propTypes in favor of TypeScript types.super.componentWillReceiveProps, check whether it's still there and use the correct name if needed.getChildContext* methods to getContext*, e.g. getChildContextName -> getContextName.onSubmit are no longer allowed. To return an error or some result, return a Promise instead.filterDOMProps.registered is now read-only.any.filterDOMProps.register is now type safe and requires FilterDOMProps interface extension.getField, getSubfields, and getType of all bridges are now memoized. If possible, do the same for custom bridges for a potential performance gain.NumField in most themes as it works as expected in React 16 and later. If you have a custom NumField in your project, do revise its implementation for a potential performance gain.diff
-import BaseForm from 'uniforms/BaseForm';
+import { BaseForm } from 'uniforms';
Most helpful comment
_(this comment will be updated)_
NOTE: This guide is designed to help you through the migration. If you went through it and encountered any problems - do let us know. For more information on _why_ certain changes were made, see the
CHANGELOG.md.NOTE: When migrating to v3, use the newest version. Gradual updates will take more time and won't ease this process.
Validation flow changes
Bridge validators have to return errors instead of throwing them.
onSubmitSuccessandonSubmitFailure. Perform all needed operations directly in theonSubmit:diff -onSubmit={onSubmit} -onSubmitSuccess={onSubmitSuccess} -onSubmitFailure={onSubmitFailure} +onSubmit={model => { <ul> <li>const result = onSubmit(model);</li> <li>result.then(onSubmitSuccess, onSubmitFailure);</li> <li>return result;<br /> +}}`<br />onValidateis no longer using callbacks. The error (or the lack of it) has to be returned either synchronously or asynchronously (i.e. wrapped in a promise).diff -onValidate={(error, done) => done(error)} +onValidate={async error => error}context,contextTypes,childContextTypes, orgetChildContext*methods directly, there's nothing to do.useFormhook (functional components),contextTypestatic property (class components), or<context.Consumer />(both).context, is exported from theuniformspackage.changed,changedMap,submitting, andvalidatingwere lifted from thestateproperty to the root.AutoForm.state.modelSync. UseAutoForm.state.modelinstead.BaseField. UseconnectFieldoruseFieldinstead.BaseForm.getChangedKeys. UsechangedKeysdirectly.BaseForm.state.bridge. UseBaseForm.props.schemainstead.Bridge.check. WithoutcreateSchemaBridgeit's no longer needed.baseFieldfromconnectFieldoptions. There's no one solution here and it may require additional changes, depending on the usage.createSchemaBridge. Now all*Bridgeinstances have to be created manually.ensureValuefromconnectFieldoptions. That meansundefinedwill no longer be automatically passed to the field as''. Usevalue ?? ''instead. This option was enabled by default, therefore it will impact all your custom fields.includeParentfromconnectFieldoptions. UseuseFieldas many times as needed instead.tsx const parentName = joinName(joinName(null, props.name).slice(0, -1)); const parentField = useField(parentName, {}, { absoluteName: true })[0];injectName. In most cases, it can be safely omitted.mapPropsfromconnectFieldoptions. Map props directly in the component.nothing. Usenullinstead.propTypesin favor of TypeScript types.super.componentWillReceiveProps, check whether it's still there and use the correct name if needed.getChildContext*methods togetContext*, e.g.getChildContextName->getContextName.onSubmitare no longer allowed. To return an error or some result, return aPromiseinstead.filterDOMProps.registeredis now read-only.any.filterDOMProps.registeris now type safe and requiresFilterDOMPropsinterface extension.getField,getSubfields, andgetTypeof all bridges are now memoized. If possible, do the same for custom bridges for a potential performance gain.NumFieldin most themes as it works as expected in React 16 and later. If you have a customNumFieldin your project, do revise its implementation for a potential performance gain.diff -import BaseForm from 'uniforms/BaseForm'; +import { BaseForm } from 'uniforms';