Form of v4 does not need to create context by calling `Form.create()`. Form now has it's own data scope and you don't need `getFieldDecorator` anymore. Just use Form.Item directly:
Since `Form.create()` is removed, methods like `onFieldsChange` have moved to `Form` and form state is controlled by a `fields` prop. ref [example](/components/form/#components-form-demo-global-state)。
New Form uses incremental update which only updates related field. So if there is some linkage between fields or updates with the whole form, you can use [`dependencies`](/components/form/#dependencies) or [`shouldUpdate`](/components/form/#shouldUpdate) to handle that.
You need to listen to `onSubmit` and call `validateFields` to handle validation in old Form. New Form provides `onFinish` which will only trigger when validation has passed:
In v3, modifying the `initialValue` of un-operated field will update the field value synchronously, which is a bug. However, since it has been used as a feature for a long time, we have not fixed it. In v4, the bug has been fixed. `initialValues` only takes effect when initializing and resetting the form.
### Nested field paths using arrays
In the past versions we used `.` to represent nested paths (such as `user.name` to represent `{ user: { name: '' } }`). However, in some backend systems, `.` is also included in the variable name. This causes the user to need additional code to convert, so in the new version, nested paths are represented by arrays to avoid unexpected behavior (eg `['user', 'name']`).
Therefore, paths returned by methods such as `getFieldsError` are always in an array form for the user to handle:
`validateFields` will return a Promise, so you can handle the error with `async/await` or `then/catch`. It is no longer necessary to determine if `errors` is empty: