Skip to content

Instantly share code, notes, and snippets.

@danielmahal
Last active June 7, 2017 19:47
Show Gist options
  • Save danielmahal/d533a385ec15834ddb50 to your computer and use it in GitHub Desktop.
Save danielmahal/d533a385ec15834ddb50 to your computer and use it in GitHub Desktop.
Firebase/React decorator
import React, {PropTypes} from 'react';
import firebase from 'decorators/firebase';
@firebase({
items: '/items',
// or
// items: (props) => `/${props.id}/items`,
// items: (props) => ref.child('items'),
})
export default class Component extends React.Component {
static propTypes = {
items: PropTypes.object.isRequired,
};
render() {
const {items} = this.props;
return (
<div>
Count: {Object.keys(items).length} items
</div>
);
}
}
import React from 'react';
import difference from 'lodash/array/difference';
import mapValues from 'lodash/object/mapValues';
import forEach from 'lodash/collection/forEach';
import isString from 'lodash/lang/isString';
import ref from 'ref';
export default function firebase(subscriptions, {placeholder = null} = {}) {
return function decorator(Component) {
return class Firebase extends React.Component {
subscribe(key, subscriptionRef) {
const onValue = snapshot => {
this.setState({
[key]: snapshot.val(),
});
};
subscriptionRef.on('value', onValue);
return function unsubscribe() {
subscriptionRef.off('value', onValue);
};
}
componentDidMount() {
this.subscriptions = mapValues(subscriptions, (getPath, key) => {
const path = getPath(this.props);
const subscriptionRef = isString(path) ? ref.child(path) : path;
return this.subscribe(key, subscriptionRef);
});
}
componentWillUnmount() {
forEach(this.subscriptions, unsubscribe => unsubscribe());
}
render() {
const stateKeys = Object.keys(this.state || {});
const subscriptionKeys = Object.keys(subscriptions);
const pending = difference(subscriptionKeys, stateKeys);
if (pending.length) {
return placeholder;
}
return <Component {...this.props} {...this.state} />;
}
};
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment