Last active
February 5, 2016 11:34
-
-
Save mjackson/5b5d87c24907fa4a32ea to your computer and use it in GitHub Desktop.
A simple mixin for React components that need to bind state to a Firebase ref
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var Firebase = require('firebase'); | |
var baseRef = new Firebase('https://my-firebase.firebaseio.com'); | |
function getSnapshotValue(snapshot) { | |
return snapshot.val(); | |
} | |
/** | |
* A mixin for components that want to bind the value of a state variable | |
* to the value at a Firebase ref. | |
*/ | |
var FirebaseStateMixin = { | |
componentWillMount: function () { | |
this.firebaseRefs = {}; | |
}, | |
componentWillUnmount: function () { | |
for (var name in this.firebaseRefs) | |
this.unbindState(name); | |
}, | |
/** | |
* Destroys the one-way binding between Firebase and the state variable | |
* with the given name, if one exists. | |
*/ | |
unbindState: function (name) { | |
if (!this.firebaseRefs[name]) | |
return; | |
this.firebaseRefs[name].off('value'); | |
delete this.firebaseRefs[name]; | |
}, | |
/** | |
* Sets up a one-way binding from the given ref to the state variable with | |
* the given name. The createValueFromSnapshot function is used to coerce | |
* a snapshot to the value of the variable. If not given, it defaults to | |
* using snapshot.val(). Returns the ref. | |
* | |
* Note: Binding to the same value twice overwrites the previous binding. | |
*/ | |
bindState: function (name, ref, createValueFromSnapshot) { | |
createValueFromSnapshot = createValueFromSnapshot || getSnapshotValue; | |
if (this.firebaseRefs[name]) | |
this.unbindState(name); // Automatically unbind. | |
if (typeof ref === 'string') | |
ref = baseRef.child(ref); | |
ref.on('value', function (snapshot) { | |
if (!this.isMounted()) | |
return; | |
var newState = {}; | |
newState[name] = createValueFromSnapshot(snapshot); | |
if (this.componentWillReceiveBoundState) | |
this.componentWillReceiveBoundState(newState); | |
this.setState(newState); | |
}, this); | |
return ref; | |
}, | |
/** | |
* Uses this.bindState() to setup a one-way binding between the given ref | |
* and the state variable with the given name. The value of the variable will | |
* be an array created from the children of the snapshot in order of precedence. | |
* The createValueFromSnapshot function is used to create values in the array. | |
* If not given, it defaults to using snapshot.val(). Returns the ref. | |
*/ | |
bindStateAsArray: function (name, ref, createValueFromSnapshot) { | |
createValueFromSnapshot = createValueFromSnapshot || getSnapshotValue; | |
return this.bindState(name, ref, function (snapshot) { | |
var values = []; | |
snapshot.forEach(function (s) { | |
values.push(createValueFromSnapshot(s)); | |
}); | |
return values; | |
}); | |
}, | |
/** | |
* Uses this.bindState() to setup a one-way binding between the given ref | |
* and the state variable with the given name. The value of the variable will | |
* be the number of children of the snapshot (i.e. snapshot.numChildren()). | |
*/ | |
bindStateAsCount: function (name, ref) { | |
return this.bindState(name, ref, function (snapshot) { | |
return snapshot.numChildren(); | |
}); | |
} | |
}; | |
module.exports = FirebaseStateMixin; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment