Form.js 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. import _extends from "@babel/runtime/helpers/esm/extends";
  2. import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
  3. import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
  4. import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
  5. var _excluded = ["name", "initialValues", "fields", "form", "preserve", "children", "component", "validateMessages", "validateTrigger", "onValuesChange", "onFieldsChange", "onFinish", "onFinishFailed", "clearOnDestroy"];
  6. import * as React from 'react';
  7. import useForm from "./useForm";
  8. import FieldContext, { HOOK_MARK } from "./FieldContext";
  9. import FormContext from "./FormContext";
  10. import { isSimilar } from "./utils/valueUtil";
  11. import ListContext from "./ListContext";
  12. var Form = function Form(_ref, ref) {
  13. var name = _ref.name,
  14. initialValues = _ref.initialValues,
  15. fields = _ref.fields,
  16. form = _ref.form,
  17. preserve = _ref.preserve,
  18. children = _ref.children,
  19. _ref$component = _ref.component,
  20. Component = _ref$component === void 0 ? 'form' : _ref$component,
  21. validateMessages = _ref.validateMessages,
  22. _ref$validateTrigger = _ref.validateTrigger,
  23. validateTrigger = _ref$validateTrigger === void 0 ? 'onChange' : _ref$validateTrigger,
  24. onValuesChange = _ref.onValuesChange,
  25. _onFieldsChange = _ref.onFieldsChange,
  26. _onFinish = _ref.onFinish,
  27. onFinishFailed = _ref.onFinishFailed,
  28. clearOnDestroy = _ref.clearOnDestroy,
  29. restProps = _objectWithoutProperties(_ref, _excluded);
  30. var nativeElementRef = React.useRef(null);
  31. var formContext = React.useContext(FormContext);
  32. // We customize handle event since Context will makes all the consumer re-render:
  33. // https://reactjs.org/docs/context.html#contextprovider
  34. var _useForm = useForm(form),
  35. _useForm2 = _slicedToArray(_useForm, 1),
  36. formInstance = _useForm2[0];
  37. var _getInternalHooks = formInstance.getInternalHooks(HOOK_MARK),
  38. useSubscribe = _getInternalHooks.useSubscribe,
  39. setInitialValues = _getInternalHooks.setInitialValues,
  40. setCallbacks = _getInternalHooks.setCallbacks,
  41. setValidateMessages = _getInternalHooks.setValidateMessages,
  42. setPreserve = _getInternalHooks.setPreserve,
  43. destroyForm = _getInternalHooks.destroyForm;
  44. // Pass ref with form instance
  45. React.useImperativeHandle(ref, function () {
  46. return _objectSpread(_objectSpread({}, formInstance), {}, {
  47. nativeElement: nativeElementRef.current
  48. });
  49. });
  50. // Register form into Context
  51. React.useEffect(function () {
  52. formContext.registerForm(name, formInstance);
  53. return function () {
  54. formContext.unregisterForm(name);
  55. };
  56. }, [formContext, formInstance, name]);
  57. // Pass props to store
  58. setValidateMessages(_objectSpread(_objectSpread({}, formContext.validateMessages), validateMessages));
  59. setCallbacks({
  60. onValuesChange: onValuesChange,
  61. onFieldsChange: function onFieldsChange(changedFields) {
  62. formContext.triggerFormChange(name, changedFields);
  63. if (_onFieldsChange) {
  64. for (var _len = arguments.length, rest = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
  65. rest[_key - 1] = arguments[_key];
  66. }
  67. _onFieldsChange.apply(void 0, [changedFields].concat(rest));
  68. }
  69. },
  70. onFinish: function onFinish(values) {
  71. formContext.triggerFormFinish(name, values);
  72. if (_onFinish) {
  73. _onFinish(values);
  74. }
  75. },
  76. onFinishFailed: onFinishFailed
  77. });
  78. setPreserve(preserve);
  79. // Set initial value, init store value when first mount
  80. var mountRef = React.useRef(null);
  81. setInitialValues(initialValues, !mountRef.current);
  82. if (!mountRef.current) {
  83. mountRef.current = true;
  84. }
  85. React.useEffect(function () {
  86. return function () {
  87. return destroyForm(clearOnDestroy);
  88. };
  89. },
  90. // eslint-disable-next-line react-hooks/exhaustive-deps
  91. []);
  92. // Prepare children by `children` type
  93. var childrenNode;
  94. var childrenRenderProps = typeof children === 'function';
  95. if (childrenRenderProps) {
  96. var _values = formInstance.getFieldsValue(true);
  97. childrenNode = children(_values, formInstance);
  98. } else {
  99. childrenNode = children;
  100. }
  101. // Not use subscribe when using render props
  102. useSubscribe(!childrenRenderProps);
  103. // Listen if fields provided. We use ref to save prev data here to avoid additional render
  104. var prevFieldsRef = React.useRef();
  105. React.useEffect(function () {
  106. if (!isSimilar(prevFieldsRef.current || [], fields || [])) {
  107. formInstance.setFields(fields || []);
  108. }
  109. prevFieldsRef.current = fields;
  110. }, [fields, formInstance]);
  111. var formContextValue = React.useMemo(function () {
  112. return _objectSpread(_objectSpread({}, formInstance), {}, {
  113. validateTrigger: validateTrigger
  114. });
  115. }, [formInstance, validateTrigger]);
  116. var wrapperNode = /*#__PURE__*/React.createElement(ListContext.Provider, {
  117. value: null
  118. }, /*#__PURE__*/React.createElement(FieldContext.Provider, {
  119. value: formContextValue
  120. }, childrenNode));
  121. if (Component === false) {
  122. return wrapperNode;
  123. }
  124. return /*#__PURE__*/React.createElement(Component, _extends({}, restProps, {
  125. ref: nativeElementRef,
  126. onSubmit: function onSubmit(event) {
  127. event.preventDefault();
  128. event.stopPropagation();
  129. formInstance.submit();
  130. },
  131. onReset: function onReset(event) {
  132. var _restProps$onReset;
  133. event.preventDefault();
  134. formInstance.resetFields();
  135. (_restProps$onReset = restProps.onReset) === null || _restProps$onReset === void 0 || _restProps$onReset.call(restProps, event);
  136. }
  137. }), wrapperNode);
  138. };
  139. export default Form;