react-redux-setstate
Version:
A HOC that overrides the React setState API to use Redux for storing component state.
138 lines (101 loc) • 5.62 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
var _defineProperty2 = require('babel-runtime/helpers/defineProperty');
var _defineProperty3 = _interopRequireDefault(_defineProperty2);
var _extends3 = require('babel-runtime/helpers/extends');
var _extends4 = _interopRequireDefault(_extends3);
var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
var _createClass2 = require('babel-runtime/helpers/createClass');
var _createClass3 = _interopRequireDefault(_createClass2);
var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');
var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
var _get2 = require('babel-runtime/helpers/get');
var _get3 = _interopRequireDefault(_get2);
var _inherits2 = require('babel-runtime/helpers/inherits');
var _inherits3 = _interopRequireDefault(_inherits2);
var _typeof2 = require('babel-runtime/helpers/typeof');
var _typeof3 = _interopRequireDefault(_typeof2);
exports.default = connectComponentState;
var _reactRedux = require('react-redux');
var _PropTypes = require('react-redux/lib/utils/PropTypes');
var _actions = require('./actions');
var _utils = require('./utils');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var componentKeyProp = '__reactReduxSetState_componentKey__';
var componentStateProp = '__reactReduxSetState_state__';
var readyInstanceProp = '__reactReduxSetState_ready__';
var tempStateInstanceProp = '__reactReduxSetState_tempState__';
function connectComponentState() {
var getComponentKey = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _utils.generateRandomKey;
var reduxStateKey = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'componentState';
var storeContextKey = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'store';
(0, _utils.assert)(typeof getComponentKey === 'undefined' ? 'undefined' : (0, _typeof3.default)(getComponentKey), 'function');
(0, _utils.assert)(typeof reduxStateKey === 'undefined' ? 'undefined' : (0, _typeof3.default)(reduxStateKey), 'string');
return function (Component) {
var WrappedComponent = function (_Component) {
(0, _inherits3.default)(WrappedComponent, _Component);
function WrappedComponent() {
(0, _classCallCheck3.default)(this, WrappedComponent);
return (0, _possibleConstructorReturn3.default)(this, (WrappedComponent.__proto__ || Object.getPrototypeOf(WrappedComponent)).apply(this, arguments));
}
(0, _createClass3.default)(WrappedComponent, [{
key: 'componentWillMount',
value: function componentWillMount() {
// Initialize state, assuming it was set in the constructor
if (this[readyInstanceProp]) {
this[readyInstanceProp]();
}
if ((0, _get3.default)(WrappedComponent.prototype.__proto__ || Object.getPrototypeOf(WrappedComponent.prototype), 'componentWillMount', this)) {
(0, _get3.default)(WrappedComponent.prototype.__proto__ || Object.getPrototypeOf(WrappedComponent.prototype), 'componentWillMount', this).call(this);
}
}
}, {
key: 'setState',
value: function setState(updater, callback) {
// todo: invoke callback
this.context[storeContextKey].dispatch((0, _actions.setState)(updater, this.props[componentKeyProp], this));
}
}, {
key: 'state',
get: function get() {
return this.props[componentStateProp] || this[tempStateInstanceProp];
},
set: function set(state) {
var _this2 = this;
// A fallback value used in the getter if the Redux action has not been
// dispatched yet, so the first render can use the initial values
this[tempStateInstanceProp] = state;
// Only allow state to be initialized once. It must be done in the
// constructor or it will be ignored.
if (state == null || this[readyInstanceProp]) {
return;
}
(0, _utils.assert)(typeof state === 'undefined' ? 'undefined' : (0, _typeof3.default)(state), 'object');
// context has not been evaluated in the constructor; save a function
// to execute in componentWillMount
this[readyInstanceProp] = function () {
_this2.context[storeContextKey].dispatch((0, _actions.setState)(state, _this2.props[componentKeyProp], _this2, true));
};
}
}]);
return WrappedComponent;
}(Component);
Object.assign(WrappedComponent, Component);
WrappedComponent.displayName = Component.displayName || Component.name;
WrappedComponent.contextTypes = (0, _extends4.default)({}, Component.contextTypes || {}, (0, _defineProperty3.default)({}, storeContextKey, _PropTypes.storeShape));
return (0, _reactRedux.connect)(
// Memoize mapStateToProps so that getComponentKey is called once when the
// element is constructed for the first time
function (state, props) {
var componentKey = getComponentKey(props, Component);
return function (state, props) {
var _ref;
return _ref = {}, (0, _defineProperty3.default)(_ref, componentKeyProp, componentKey), (0, _defineProperty3.default)(_ref, componentStateProp, state[reduxStateKey][componentKey]), _ref;
};
}, {})(WrappedComponent);
};
}
//# sourceMappingURL=connectComponentState.js.map