UNPKG

@atlaskit/form

Version:

A form allows people to input information.

76 lines (71 loc) 3.18 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.useFormState = void 0; var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); var _react = require("react"); var _form = require("./form"); // Constantized to avoid a new object reference built every call var defaultSubscriptionConfig = { values: true }; /** * Build a simple hash for a given subscription object for use in a `useMemo` dependencies array. * This is because `{ values: true } !== { values: true }`, but `'values:true|' === 'values:true|'` * * @example { values: true, dirty: false } => 'values:true|dirty:false|' */ var getSubscriptionHash = function getSubscriptionHash(subscriptionConfig) { var hash = ''; for (var key in subscriptionConfig) { if (subscriptionConfig.hasOwnProperty(key)) { hash += "".concat(key, ":").concat(subscriptionConfig[key], "|"); } } return hash; }; /** * A hook to return a recent form state for use within the `<Form>` as it requires context access. * This is useful for previewing form state, or for building custom fields that need to react to form state. * * This should not be used as a way to persist form state into another form state, use `onSubmit` for proper form handling. * * @note On the initial render, this should be `undefined` as our form has not provided any state. */ var useFormState = exports.useFormState = function useFormState() { var subscriptionConfig = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : defaultSubscriptionConfig; var _useContext = (0, _react.useContext)(_form.FormContext), subscribe = _useContext.subscribe; var _useState = (0, _react.useState)(), _useState2 = (0, _slicedToArray2.default)(_useState, 2), state = _useState2[0], setState = _useState2[1]; /** * A hash for us to shallow compare the subscriptionConfig object to react to shallow changes, but avoid referential changes. * We avoid computing the hash if the subscription config has referential equality altogether. */ var subscriptionConfigHash = (0, _react.useMemo)(function () { return getSubscriptionHash(subscriptionConfig); }, [subscriptionConfig]); /** * Return a memoized version of the subscription config to only react to shallow changes, not referential changes. * Eg. calling `useFormState({ values: true })` twice will result in two different objects by reference, but not by shallow comparison. * This will ensure we don't re-subscribe to the form state when the subscription config is the same. */ var config = (0, _react.useMemo)(function () { return subscriptionConfig; }, // eslint-disable-next-line react-hooks/exhaustive-deps -- intentionally controlled with a hash to have an explicit shallow comparison [subscriptionConfigHash]); (0, _react.useEffect)(function () { var unsubscribe = subscribe(function (formState) { setState(formState); }, config); return function () { return unsubscribe(); }; }, [subscribe, config]); return state; };