react-sizes
Advanced tools
Comparing version 0.2.0 to 0.3.0
@@ -15,12 +15,6 @@ 'use strict'; | ||
var _uuid = require('uuid'); | ||
var _lodash = require('lodash.throttle'); | ||
var _lodash = require('lodash.keys'); | ||
var _lodash2 = _interopRequireDefault(_lodash); | ||
var _lodash3 = require('lodash.throttle'); | ||
var _lodash4 = _interopRequireDefault(_lodash3); | ||
var _presets = require('./presets'); | ||
@@ -52,7 +46,4 @@ | ||
var debug = process.env.NODE_ENV !== 'production'; | ||
var debug = process && process.env && process.env.NODE_ENV === 'debug'; | ||
var resizeListener = void 0; | ||
var listeners = {}; | ||
var withSizes = function withSizes() { | ||
@@ -67,3 +58,3 @@ for (var _len = arguments.length, mappedSizesToProps = Array(_len), _key = 0; _key < _len; _key++) { | ||
var parseMappedSizesToProps = function parseMappedSizesToProps(dimensions, props) { | ||
var propsToPass = mappedSizesToProps.map(function (check) { | ||
return mappedSizesToProps.map(function (check) { | ||
return check(dimensions, props); | ||
@@ -73,10 +64,8 @@ }).reduce(function (acc, props) { | ||
}, {}); | ||
return propsToPass; | ||
}; | ||
return _temp2 = _class = function (_Component) { | ||
_inherits(_class, _Component); | ||
_inherits(ComponentWithSizes, _Component); | ||
function _class() { | ||
function ComponentWithSizes() { | ||
var _ref; | ||
@@ -86,3 +75,3 @@ | ||
_classCallCheck(this, _class); | ||
_classCallCheck(this, ComponentWithSizes); | ||
@@ -93,32 +82,30 @@ for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { | ||
return _ret = (_temp = (_this = _possibleConstructorReturn(this, (_ref = _class.__proto__ || Object.getPrototypeOf(_class)).call.apply(_ref, [this].concat(args))), _this), _this.state = { | ||
id: 'A' + (0, _uuid.v4)(), | ||
return _ret = (_temp = (_this = _possibleConstructorReturn(this, (_ref = ComponentWithSizes.__proto__ || Object.getPrototypeOf(ComponentWithSizes)).call.apply(_ref, [this].concat(args))), _this), _this.state = { | ||
initialSizes: (0, _getWindowSizes2.default)(window), | ||
propsToPass: parseMappedSizesToProps((0, _getWindowSizes2.default)(window), _this.props) | ||
}, _this.listenerCallback = function (sizes) { | ||
var propsToPass = parseMappedSizesToProps(sizes, _this.props); | ||
/* Dispatching & Throttling */ | ||
}, _this.dispatchSizes = function () { | ||
var propsToPass = parseMappedSizesToProps((0, _getWindowSizes2.default)(window), _this.props); | ||
if ((0, _shallowDiff2.default)(propsToPass, _this.state.propsToPass)) { | ||
_this.setState({ propsToPass: propsToPass }); | ||
} | ||
}, _this.dispatchSizes = function () { | ||
(0, _lodash2.default)(listeners).forEach(function (key) { | ||
var callback = listeners[key]; | ||
if (typeof callback === 'function') { | ||
callback((0, _getWindowSizes2.default)(window)); | ||
} | ||
}); | ||
}, _this.throttledWindowResize = (0, _lodash4.default)(_this.dispatchSizes, 200), _temp), _possibleConstructorReturn(_this, _ret); | ||
}, _this.throttledDispatchSizes = (0, _lodash2.default)(_this.dispatchSizes, 200), _temp), _possibleConstructorReturn(_this, _ret); | ||
} | ||
_createClass(_class, [{ | ||
_createClass(ComponentWithSizes, [{ | ||
key: 'componentDidMount', | ||
/* Lifecycles */ | ||
value: function componentDidMount() { | ||
if (!resizeListener) { | ||
resizeListener = window.addEventListener('resize', this.throttledWindowResize); | ||
window.addEventListener('resize', this.throttledDispatchSizes); | ||
/* dispatch if aren't computed on first render */ | ||
if (!this.state.initialSizes.canUseDOM) { | ||
this.dispatchSizes(); | ||
} | ||
listeners[this.state.id] = this.listenerCallback; | ||
this.dispatchSizes(); | ||
} | ||
@@ -128,7 +115,3 @@ }, { | ||
value: function componentWillUnmount() { | ||
delete listeners[this.state.id]; | ||
if ((0, _lodash2.default)(listeners).length < 1) { | ||
window.removeEventListener('resize', this.throttledWindowResize); | ||
resizeListener = null; | ||
} | ||
window.removeEventListener('resize', this.throttledDispatchSizes); | ||
} | ||
@@ -143,3 +126,3 @@ }, { | ||
return _class; | ||
return ComponentWithSizes; | ||
}(_react.Component), _class.displayName = 'withSizes(' + (0, _getDisplayName2.default)(WrappedComponent) + ')', _temp2; | ||
@@ -146,0 +129,0 @@ }; |
{ | ||
"name": "react-sizes", | ||
"version": "0.2.0", | ||
"version": "0.3.0", | ||
"description": "Hoc to easily map window sizes to props.", | ||
@@ -11,3 +11,3 @@ "main": "lib/index.js", | ||
"prepublish": "npm run lint && npm run clear && npm run build", | ||
"storybook": "start-storybook -p 6006", | ||
"storybook": "cross-env NODE_ENV=debug start-storybook -p 6006", | ||
"build-storybook": "build-storybook" | ||
@@ -14,0 +14,0 @@ }, |
@@ -172,19 +172,2 @@ ![react-sizes](./logo.png) | ||
## Performance Notes | ||
#### Global listener | ||
Window resize event listener is grouped at one global listener only. | ||
So you can have as many components as you want using Sizes hoc, which will not have multiple resize listeners, | ||
but only one that will dispatch for all instances. | ||
Don't worry, Sizes handles `componentWillUnmount` to remove unnecessary callbacks. | ||
When each component unmounted, it unsubscribe for global dispatches, and when last component is unmounted, | ||
the listener is removed. | ||
#### Throttle | ||
By now the listener callback is hardcoded as [throttle](https://css-tricks.com/debouncing-throttling-explained-examples/) | ||
function of 200ms. Because of having a global listener, we have a limitation on changing this behavior. | ||
I don't see it as tradeoff, and I think it can have good workarounds. | ||
Then, for the future, I intend to work to bring a solution to this important customization. | ||
## Guide | ||
@@ -219,2 +202,7 @@ | ||
## Performance Notes | ||
#### Shallow Compare | ||
React Sizes do a shallow compare in props generated from `mapSizesToProps` (called `propsToPass`), so it will only rerender when they really change. If you create a deep data sctructure, this can generate false positives. In these cases, we recommend using immutable for a more reliable shallow compare result. Or just don't use deep data structures, if possible. | ||
## Contribute | ||
@@ -221,0 +209,0 @@ |
/* eslint-disable no-console */ | ||
import React, { Component } from 'react' | ||
import { v4 } from 'uuid' | ||
import keys from 'lodash.keys' | ||
import throttle from 'lodash.throttle' | ||
@@ -14,44 +12,23 @@ | ||
const debug = process.env.NODE_ENV !== 'production' | ||
const debug = process && process.env && | ||
process.env.NODE_ENV === 'debug' | ||
let resizeListener | ||
const listeners = {} | ||
const withSizes = (...mappedSizesToProps) => (WrappedComponent) => { | ||
const parseMappedSizesToProps = (dimensions, props) => { | ||
const propsToPass = mappedSizesToProps | ||
const parseMappedSizesToProps = (dimensions, props) => | ||
mappedSizesToProps | ||
.map(check => check(dimensions, props)) | ||
.reduce((acc, props) => ({...acc, ...props}), {}) | ||
.reduce((acc, props) => ({ ...acc, ...props }), {}) | ||
return propsToPass | ||
} | ||
return class ComponentWithSizes extends Component { | ||
static displayName = `withSizes(${getDisplayName(WrappedComponent)})` | ||
return class extends Component { | ||
static displayName = `withSizes(${getDisplayName(WrappedComponent)})`; | ||
state = { | ||
id: `A${v4()}`, | ||
initialSizes: getWindowSizes(window), | ||
propsToPass: parseMappedSizesToProps(getWindowSizes(window), this.props), | ||
}; | ||
componentDidMount() { | ||
if (!resizeListener) { | ||
resizeListener = window.addEventListener('resize', this.throttledWindowResize) | ||
} | ||
listeners[this.state.id] = this.listenerCallback | ||
this.dispatchSizes() | ||
} | ||
componentWillUnmount() { | ||
delete listeners[this.state.id] | ||
if (keys(listeners).length < 1) { | ||
window.removeEventListener('resize', this.throttledWindowResize) | ||
resizeListener = null | ||
} | ||
} | ||
/* Dispatching & Throttling */ | ||
listenerCallback = (sizes) => { | ||
const propsToPass = parseMappedSizesToProps(sizes, this.props) | ||
dispatchSizes = () => { | ||
const propsToPass = parseMappedSizesToProps(getWindowSizes(window), this.props) | ||
@@ -63,16 +40,21 @@ if (shallowDiff(propsToPass, this.state.propsToPass)) { | ||
dispatchSizes = () => { | ||
keys(listeners).forEach(key => { | ||
const callback = listeners[key] | ||
throttledDispatchSizes = ( | ||
throttle(this.dispatchSizes, 200) | ||
) | ||
if (typeof callback === 'function') { | ||
callback(getWindowSizes(window)) | ||
} | ||
}) | ||
}; | ||
/* Lifecycles */ | ||
throttledWindowResize = ( | ||
throttle(this.dispatchSizes, 200) | ||
); | ||
componentDidMount() { | ||
window.addEventListener('resize', this.throttledDispatchSizes) | ||
/* dispatch if aren't computed on first render */ | ||
if (!this.state.initialSizes.canUseDOM) { | ||
this.dispatchSizes() | ||
} | ||
} | ||
componentWillUnmount() { | ||
window.removeEventListener('resize', this.throttledDispatchSizes) | ||
} | ||
render() { | ||
@@ -79,0 +61,0 @@ if (debug) console.log('render', this.state.propsToPass) |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
0
26369
239
210
4