holen
Version:
Declarative fetch in React
147 lines (122 loc) • 4.86 kB
JavaScript
import React from 'react';
import PropTypes from 'prop-types';
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
function childrenToArray(children) {
return Array.isArray && Array.isArray(children) ? children : [].concat(children);
}
var Holen = function (_React$Component) {
_inherits(Holen, _React$Component);
function Holen() {
var _temp, _this, _ret;
_classCallCheck(this, Holen);
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
return _ret = (_temp = (_this = _possibleConstructorReturn(this, _React$Component.call.apply(_React$Component, [this].concat(args))), _this), _this.state = {
fetching: !_this.props.lazy,
response: undefined,
data: undefined,
error: undefined
}, _this.doFetch = function (options) {
var _Object$assign = Object.assign({}, _this.props, options),
url = _Object$assign.url,
body = _Object$assign.body,
credentials = _Object$assign.credentials,
headers = _Object$assign.headers,
method = _Object$assign.method;
_this.setState({ fetching: true });
var updateState = function updateState(error, response) {
if (_this.willUnmount) {
return;
}
_this.setState({
data: response && response.data ? _this.props.transformResponse(response.data) : undefined,
error: error,
fetching: false,
response: response
}, function () {
_this.props.onResponse(error, response);
});
};
// eslint-disable-next-line no-undef
return fetch(url, {
body: body,
credentials: credentials,
headers: headers,
method: method
}).then(function (res) {
if (_this.willUnmount) {
return;
}
var bodyMethod = res[_this.props.type];
return bodyMethod.apply(res).then(function (data) {
res.data = data;
return res;
});
}).then(function (res) {
updateState(undefined, res);
return res;
}).catch(function (e) {
updateState(e, undefined);
return e;
});
}, _temp), _possibleConstructorReturn(_this, _ret);
}
Holen.prototype.componentDidMount = function componentDidMount() {
if (this.props.lazy) {
return;
}
this.doFetch();
};
Holen.prototype.componentWillReceiveProps = function componentWillReceiveProps(nextProps) {
var _this2 = this;
// only refresh when keys with primitive types change
var refreshProps = ['url', 'method', 'lazy', 'type', 'body'];
if (refreshProps.some(function (key) {
return _this2.props[key] !== nextProps[key];
})) {
this.doFetch(nextProps);
}
};
Holen.prototype.componentWillUnmount = function componentWillUnmount() {
this.willUnmount = true;
};
Holen.prototype.render = function render() {
if (!this.props.children) {
return null;
}
var renderFn = this.props.render || childrenToArray(this.props.children)[0];
return renderFn({
fetching: this.state.fetching,
response: this.state.response,
data: this.state.data,
error: this.state.error,
fetch: this.doFetch
}) || null;
};
return Holen;
}(React.Component);
Holen.propTypes = {
body: PropTypes.any,
children: PropTypes.func,
credentials: PropTypes.string,
headers: PropTypes.object,
lazy: PropTypes.bool,
method: PropTypes.oneOf(['get', 'post', 'put', 'patch', 'delete', 'GET', 'POST', 'PUT', 'PATCH', 'DELETE']),
onResponse: PropTypes.func,
url: PropTypes.string.isRequired,
type: PropTypes.oneOf(['json', 'text', 'blob']),
transformResponse: PropTypes.func
};
Holen.defaultProps = {
method: 'get',
type: 'json',
onResponse: function onResponse() {},
transformResponse: function transformResponse(data) {
return data;
}
};
export default Holen;
//# sourceMappingURL=holen.es.js.map