UNPKG

redux-form

Version:

A higher order component decorator for forms using Redux and React

200 lines (176 loc) 7.43 kB
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/objectWithoutPropertiesLoose"; import _createClass from "@babel/runtime/helpers/createClass"; import _inheritsLoose from "@babel/runtime/helpers/inheritsLoose"; import _mapValues from "lodash/mapValues"; import React, { Component, createElement } from 'react'; import PropTypes from 'prop-types'; import { connect } from 'react-redux'; import { bindActionCreators } from 'redux'; import createFieldArrayProps from './createFieldArrayProps'; import plain from './structure/plain'; import validateComponentProp from './util/validateComponentProp'; var propsToNotUpdateFor = ['_reduxForm', 'value']; export default function createConnectedFieldArray(structure) { var deepEqual = structure.deepEqual, getIn = structure.getIn, size = structure.size, equals = structure.equals, orderChanged = structure.orderChanged; var getSyncError = function getSyncError(syncErrors, name) { // For an array, the error can _ONLY_ be under _error. // This is why this getSyncError is not the same as the // one in Field. return plain.getIn(syncErrors, name + "._error"); }; var getSyncWarning = function getSyncWarning(syncWarnings, name) { // For an array, the warning can _ONLY_ be under _warning. // This is why this getSyncError is not the same as the // one in Field. return getIn(syncWarnings, name + "._warning"); }; var ConnectedFieldArray = /*#__PURE__*/ function (_Component) { _inheritsLoose(ConnectedFieldArray, _Component); function ConnectedFieldArray() { var _this; for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } _this = _Component.call.apply(_Component, [this].concat(args)) || this; _this.ref = React.createRef(); _this.getValue = function (index) { return _this.props.value && getIn(_this.props.value, String(index)); }; return _this; } var _proto = ConnectedFieldArray.prototype; _proto.shouldComponentUpdate = function shouldComponentUpdate(nextProps) { var _this2 = this; // Update if the elements of the value array was updated. var thisValue = this.props.value; var nextValue = nextProps.value; if (thisValue && nextValue) { var nextValueItemsSame = equals(nextValue, thisValue); //.every(val => ~thisValue.indexOf(val)) var nextValueItemsOrderChanged = orderChanged(thisValue, nextValue); var thisValueLength = thisValue.length || thisValue.size; var nextValueLength = nextValue.length || nextValue.size; if (thisValueLength !== nextValueLength || nextValueItemsSame && nextValueItemsOrderChanged || nextProps.rerenderOnEveryChange && thisValue.some(function (val, index) { return !deepEqual(val, nextValue[index]); })) { return true; } } var nextPropsKeys = Object.keys(nextProps); var thisPropsKeys = Object.keys(this.props); // if we have children, we MUST update in React 16 // https://twitter.com/erikras/status/915866544558788608 return !!(this.props.children || nextProps.children || nextPropsKeys.length !== thisPropsKeys.length || nextPropsKeys.some(function (prop) { // useful to debug rerenders // if (!plain.deepEqual(this.props[ prop ], nextProps[ prop ])) { // console.info(prop, 'changed', this.props[ prop ], '==>', nextProps[ prop ]) // } return !~propsToNotUpdateFor.indexOf(prop) && !deepEqual(_this2.props[prop], nextProps[prop]); })); }; _proto.getRenderedComponent = function getRenderedComponent() { return this.ref.current; }; _proto.render = function render() { var _this$props = this.props, component = _this$props.component, forwardRef = _this$props.forwardRef, name = _this$props.name, _reduxForm = _this$props._reduxForm, validate = _this$props.validate, warn = _this$props.warn, rerenderOnEveryChange = _this$props.rerenderOnEveryChange, rest = _objectWithoutPropertiesLoose(_this$props, ["component", "forwardRef", "name", "_reduxForm", "validate", "warn", "rerenderOnEveryChange"]); var props = createFieldArrayProps(structure, name, _reduxForm.form, _reduxForm.sectionPrefix, this.getValue, rest); if (forwardRef) { props.ref = this.ref; } return createElement(component, props); }; _createClass(ConnectedFieldArray, [{ key: "dirty", get: function get() { return this.props.dirty; } }, { key: "pristine", get: function get() { return this.props.pristine; } }, { key: "value", get: function get() { return this.props.value; } }]); return ConnectedFieldArray; }(Component); ConnectedFieldArray.propTypes = { component: validateComponentProp, props: PropTypes.object, rerenderOnEveryChange: PropTypes.bool }; ConnectedFieldArray.defaultProps = { rerenderOnEveryChange: false }; var connector = connect(function (state, ownProps) { var name = ownProps.name, _ownProps$_reduxForm = ownProps._reduxForm, initialValues = _ownProps$_reduxForm.initialValues, getFormState = _ownProps$_reduxForm.getFormState; var formState = getFormState(state); var initial = getIn(formState, "initial." + name) || initialValues && getIn(initialValues, name); var value = getIn(formState, "values." + name); var submitting = getIn(formState, 'submitting'); var syncError = getSyncError(getIn(formState, 'syncErrors'), name); var syncWarning = getSyncWarning(getIn(formState, 'syncWarnings'), name); var pristine = deepEqual(value, initial); return { asyncError: getIn(formState, "asyncErrors." + name + "._error"), dirty: !pristine, pristine: pristine, state: getIn(formState, "fields." + name), submitError: getIn(formState, "submitErrors." + name + "._error"), submitFailed: getIn(formState, 'submitFailed'), submitting: submitting, syncError: syncError, syncWarning: syncWarning, value: value, length: size(value) }; }, function (dispatch, ownProps) { var name = ownProps.name, _reduxForm = ownProps._reduxForm; var arrayInsert = _reduxForm.arrayInsert, arrayMove = _reduxForm.arrayMove, arrayPop = _reduxForm.arrayPop, arrayPush = _reduxForm.arrayPush, arrayRemove = _reduxForm.arrayRemove, arrayRemoveAll = _reduxForm.arrayRemoveAll, arrayShift = _reduxForm.arrayShift, arraySplice = _reduxForm.arraySplice, arraySwap = _reduxForm.arraySwap, arrayUnshift = _reduxForm.arrayUnshift; return _mapValues({ arrayInsert: arrayInsert, arrayMove: arrayMove, arrayPop: arrayPop, arrayPush: arrayPush, arrayRemove: arrayRemove, arrayRemoveAll: arrayRemoveAll, arrayShift: arrayShift, arraySplice: arraySplice, arraySwap: arraySwap, arrayUnshift: arrayUnshift }, function (actionCreator) { return bindActionCreators(actionCreator.bind(null, name), dispatch); }); }, undefined, { forwardRef: true }); return connector(ConnectedFieldArray); }