Skip to content

Commit

Permalink
🔨 currying and optimizing (#69)
Browse files Browse the repository at this point in the history
  • Loading branch information
Fabien JUIF authored May 2, 2017
1 parent 74bbc27 commit 21c4338
Show file tree
Hide file tree
Showing 14 changed files with 172 additions and 157 deletions.
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import loader from 'hoc-react-loader'

const Component = ({ data }) => <div>Component {JSON.stringify(data)}</div>

export default loader(Component, { print: ['data'] })
export default loader({ print: ['data'] })(Component)
```
In this case, the loader waits for `this.props.data` to be truthy, then mounts its child component and calls `this.props.load` if it exists. This is useful when the parent has control over the injected data, or when the `Component` is connected with `redux`. `this.props.load` should be injected by the parent component or injected by a `Container` (redux).

Expand All @@ -33,7 +33,7 @@ import loader from 'hoc-react-loader'
const MyLoadingIndicator = () => <div>Waiting...</div>
const Component = ({ data }) => <div>Component {data}</div>

export default loader(Component, { print: ['data'], LoadingIndicator: MyLoadingIndicator })
export default loader({ print: ['data'], LoadingIndicator: MyLoadingIndicator })(Component)
```

### Don't wait
Expand All @@ -42,7 +42,7 @@ import loader from 'hoc-react-loader'

const Component = ({ data }) => <div>Component {JSON.stringify(data)}</div>

export default loader(Component)
export default loader()(Component)
```
In this example, the loader component doesn't wait for props. `this.props.load` is called once, but the `LoadingIndicator` component isn't displayed.

Expand All @@ -52,7 +52,7 @@ import loader from 'hoc-react-loader'

const Component = ({ data }) => <div>Component {JSON.stringify(data)}</div>

export default loader(Component, { load: () => console.log('here') })
export default loader({ load: () => console.log('here') })(Component)
```
In this case, the loader calls `this.props.load` if it exists *AND* the `load` parameter, resulting in `here` to be printed.

Expand All @@ -64,7 +64,7 @@ import loader from 'hoc-react-loader'

const Component = ({ data }) => <div>Component {JSON.stringify(data)}</div>

export default loader(Component, { load: 'myLoader' })
export default loader({ load: 'myLoader' })(Component)
```
In this case, the loader calls `this.props.myLoader` if it exists.

Expand Down
159 changes: 84 additions & 75 deletions build/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,100 +43,109 @@ var getDisplayName = function getDisplayName(c) {
return c.displayName || c.name || 'Component';
};

exports.default = function (ComposedComponent) {
var _class, _temp2;

var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
exports.default = function () {
var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
LoadingIndicator = _ref.LoadingIndicator,
print = _ref.print,
load = _ref.load;

var loadFunctionName = isString(load) ? load : 'load';
var isPrintArray = Array.isArray(print);
var isPrintFunction = isFunction(print);
var isLoadFunction = isFunction(load);

var isLoaded = function isLoaded(props, context) {
// Print is undefined,
// we rely on 'props.loaded' if present
// if not, we directly print the component
if (print === undefined) {
var loaded = props.loaded;

return loaded === undefined ? true : !!loaded;
}

return _temp2 = _class = function (_Component) {
_inherits(_class, _Component);
// Print is an array
// Implicitly meaning that this is an array of props
if (isPrintArray) {
return print.map(function (p) {
return Boolean(props[p]);
}).reduce(function (allProps, currentProp) {
return allProps && currentProp;
});
}

function _class() {
var _ref2;
// Print is a function
if (isPrintFunction) {
return !!print(props, context);
}

var _temp, _this, _ret;
// Anything else
return !!print;
};

_classCallCheck(this, _class);
return function (ComposedComponent) {
var _class, _temp2;

for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
var displayName = 'Loader(' + getDisplayName(ComposedComponent) + ')';

return _ret = (_temp = (_this = _possibleConstructorReturn(this, (_ref2 = _class.__proto__ || Object.getPrototypeOf(_class)).call.apply(_ref2, [this].concat(args))), _this), _this.state = {
props: {}
}, _this.isLoaded = function () {
// Print is undefined,
// we rely on 'props.loaded' if present
// if not, we directly print the component
if (print === undefined) {
var loaded = _this.props.loaded;
return _temp2 = _class = function (_Component) {
_inherits(_class, _Component);

return loaded === undefined ? true : !!loaded;
}
function _class() {
var _ref2;

// Print is an array
// Implicitly meaning that this is an array of props
if (Array.isArray(print)) {
return print.map(function (p) {
return Boolean(_this.props[p]);
}).reduce(function (allProps, currentProp) {
return allProps && currentProp;
});
}
var _temp, _this, _ret;

// Print is a function
if (isFunction(print)) {
return !!print(_this.props, _this.context);
}
_classCallCheck(this, _class);

// Anything else
return !!print;
}, _this.omitLoadInProps = function (props) {
var isLoadAFunction = isFunction(props[loadFunctionName]);

if (isLoadAFunction) {
_this.setState({
props: _extends({}, props, _defineProperty({}, loadFunctionName, undefined))
});
} else {
_this.setState({ props: props });
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}

return isLoadAFunction;
}, _this.componentWillReceiveProps = function (nextProps) {
_this.omitLoadInProps(nextProps);
}, _temp), _possibleConstructorReturn(_this, _ret);
}
return _ret = (_temp = (_this = _possibleConstructorReturn(this, (_ref2 = _class.__proto__ || Object.getPrototypeOf(_class)).call.apply(_ref2, [this].concat(args))), _this), _this.state = {
props: {}
}, _this.omitLoadInProps = function (props) {
var isLoadAFunction = isFunction(props[loadFunctionName]);

if (isLoadAFunction) {
_this.setState({
props: _extends({}, props, _defineProperty({}, loadFunctionName, undefined))
});
} else {
_this.setState({ props: props });
}

return isLoadAFunction;
}, _this.componentWillReceiveProps = function (nextProps) {
_this.omitLoadInProps(nextProps);
}, _temp), _possibleConstructorReturn(_this, _ret);
}

_createClass(_class, [{
key: 'componentWillMount',
value: function componentWillMount() {
// Load from hoc argument
if (isFunction(load)) {
load(this.props, this.context);
_createClass(_class, [{
key: 'componentWillMount',
value: function componentWillMount() {
// Load from hoc argument
if (isLoadFunction) {
load(this.props, this.context);
}

// Load from props
if (this.omitLoadInProps(this.props)) {
this.props[loadFunctionName](this.props, this.context);
}
}

// Load from props
if (this.omitLoadInProps(this.props)) {
this.props[loadFunctionName](this.props, this.context);
}, {
key: 'render',
value: function render() {
if (!isLoaded(this.props, this.context)) {
return _react2.default.createElement(LoadingIndicator, this.state.props);
}

return _react2.default.createElement(ComposedComponent, this.state.props);
}
}
}, {
key: 'render',
value: function render() {
if (!this.isLoaded()) {
return _react2.default.createElement(LoadingIndicator, this.state.props);
}

return _react2.default.createElement(ComposedComponent, this.state.props);
}
}]);
}]);

return _class;
}(_react.Component), _class.displayName = 'Loader(' + getDisplayName(ComposedComponent) + ')', _temp2;
return _class;
}(_react.Component), _class.displayName = displayName, _temp2;
};
};
6 changes: 3 additions & 3 deletions build/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de

function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }

exports.default = function (ComposedComponent) {
var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
exports.default = function () {
var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};

var _ref$LoadingIndicator = _ref.LoadingIndicator,
LoadingIndicator = _ref$LoadingIndicator === undefined ? _TailSpin2.default : _ref$LoadingIndicator,
rest = _objectWithoutProperties(_ref, ['LoadingIndicator']);

return (0, _core2.default)(ComposedComponent, _extends({}, rest, { LoadingIndicator: LoadingIndicator }));
return (0, _core2.default)(_extends({}, rest, { LoadingIndicator: LoadingIndicator }));
};
1 change: 1 addition & 0 deletions examples/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
"hoc-react-loader": "file:../",
"lodash": "^4.15.0",
"normalize.css": "~4.2.0",
"prop-types": "^15.5.8",
"react": "15.3.0",
"react-dom": "15.3.0",
"react-highlight": "^0.8.0",
Expand Down
2 changes: 1 addition & 1 deletion examples/src/components/Examples/Base.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ Base.propTypes = {
className: PropTypes.string,
}

export default loader(Base)
export default loader()(Base)
2 changes: 1 addition & 1 deletion examples/src/components/Examples/DontWait.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@ DontWait.propTypes = {
prop: PropTypes.string.isRequired,
}

export default loader(DontWait, { print: true })
export default loader({ print: true })(DontWait)
10 changes: 5 additions & 5 deletions examples/src/components/Examples/Examples.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const Examples = ({ style, className }) => (
<Example
className={styles.example}
link="Base"
code="export&nbsp;default loader(Base)"
code="export&nbsp;default loader()(Base)"
buttons={{ 0: true }}
example={<Base />}
>
Expand All @@ -39,7 +39,7 @@ const Examples = ({ style, className }) => (
<Example
className={styles.example}
link="OneParam"
code="export&nbsp;default loader(OneParam, { print: ['prop'] })"
code="export&nbsp;default loader({ print: ['prop'] })(OneParam)"
buttons={{ 1: true }}
example={<OneParam />}
>
Expand All @@ -56,7 +56,7 @@ const Examples = ({ style, className }) => (
<Example
className={styles.example}
link="TwoParams"
code="export&nbsp;default loader(TwoParams, { print: ['prop', 'prop2'] })"
code="export&nbsp;default loader({ print: ['prop', 'prop2'] })(TwoParams)"
buttons={{ 1: true, 2: true }}
example={<TwoParams />}
>
Expand All @@ -73,7 +73,7 @@ const Examples = ({ style, className }) => (
<Example
className={styles.example}
link="DontWait"
code="export&nbsp;default loader(DontWait, { print: true })"
code="export&nbsp;default loader({ print: true })(DontWait)"
buttons={{ 0: true }}
example={<DontWait />}
>
Expand All @@ -90,7 +90,7 @@ const Examples = ({ style, className }) => (
<Example
className={styles.example}
link="LoadingIndicator"
code="export&nbsp;default loader(LoadingIndicator, { LoadingIndicator: CustomLoadingIndicator })" // eslint-disable-line
code="export&nbsp;default loader({ LoadingIndicator: CustomLoadingIndicator })(LoadingIndicator)" // eslint-disable-line
buttons={{ 0: true }}
example={<LoadingIndicator />}
>
Expand Down
2 changes: 1 addition & 1 deletion examples/src/components/Examples/LoadingIndicator.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ LoadingIndicator.propTypes = {
className: PropTypes.string,
}

export default loader(LoadingIndicator, { LoadingIndicator: CustomLoadingIndicator })
export default loader({ LoadingIndicator: CustomLoadingIndicator })(LoadingIndicator)
2 changes: 1 addition & 1 deletion examples/src/components/Examples/OneParam.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@ OneParam.propTypes = {
prop: PropTypes.string.isRequired,
}

export default loader(OneParam, { print: ['prop'] })
export default loader({ print: ['prop'] })(OneParam)
2 changes: 1 addition & 1 deletion examples/src/components/Examples/TwoParams.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ TwoParams.propTypes = {
prop2: PropTypes.string.isRequired,
}

export default loader(TwoParams, { print: ['prop', 'prop2'] })
export default loader({ print: ['prop', 'prop2'] })(TwoParams)
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "hoc-react-loader",
"version": "5.0.1",
"version": "6.0.0",
"description": "Higher order component to call a load function from props at mount.",
"main": "build/index.js",
"peerDependencies": {
Expand Down
Loading

0 comments on commit 21c4338

Please sign in to comment.