0.0.5 • Published 7 years ago
keychange v0.0.5
keychange
Utility function for reacting to specific differences in javascript objects.
basic operation
keychange
will take three objects as parameters, two to compare and another that serves as a mapping of keys to watch for changes and their handlers for the new values.
const someObject = {
foo: 'value',
bar: 'hi',
};
const anotherObject = {
foo: 'value',
bar: 'hello',
};
keyChange({
foo: anotherObject => { /* respond to new foo */ }, // Not called
bar: ({ bar }) => { alert(`bar became ${bar}!`) }, // will be called
// We can also "watch" for changes in any of a number of keys
[[ 'bar', 'foo' ]]: ({ bar }) => { alert(`bar or foo changed!`) }, // will be called
// This sort of thing is fine too
'foo,bar': ({ bar }) => { alert(`bar or foo changed!`) }, // will be called
}, someObject, anotherObject);
real life examples
Mostly useful for reducing ridiculous componentWillReceiveProps
methods.
componentWillReceiveProps = newProps => {
if (!R.equals(newProps.query, this.props.query)) {
newProps.fetchCatalogs();
}
if (!R.equals(newProps.catalogs, this.props.catalogs)) {
newProps.fetchStores(R.pluck('store_id', newProps.catalogs));
}
};
// Becomes
componentWillReceiveProps = newProps =>
keyChange({
query: ({ fetchCatalogs }) => fetchCatalogs(),
catalogs: ({ catalogs, fetchStores }) => fetchStores(R.pluck('store_id', catalogs)),
}, this.props, newProps);
componentWillReceiveProps(newProps) {
if(!R.equals(this.props.latitude, newProps.latitude) || !R.equals(this.props.longitude, newProps.longitude) {
this.map.panTo({ lat: newProps.latitude, lng: newProps.longitude })
}
}
// Becomes
componentWillReceiveProps(newProps) {
keyChange({
[['latitude', 'longitude']]: ({ latitude, longitude }) =>
this.map.panTo({ lat: latitude, lng: longitude }),
}, this.props, newProps);
}
Heck, for componentWillReceiveProps
specifically you could even do:
componentWillReceiveProps = keyChange({
query: ({ fetchCatalogs }) => fetchCatalogs(),
catalogs: ({ catalogs, fetchStores }) => fetchStores(R.pluck('store_id', catalogs)),
}, this.props);