Created
September 28, 2015 17:33
-
-
Save marcusgadbem/6abf9d18ded3fcb3c2eb to your computer and use it in GitHub Desktop.
React component pattern with a Store
This file contains hidden or 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
export class APIRateLimitError extends Error { | |
constructor(err) { | |
super('API Rate limit.'); | |
} | |
} |
This file contains hidden or 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
import { APIRateLimitError } from './errors.js'; | |
var _query = {}; | |
var _result = []; | |
var _changeListeners = []; | |
var _initCalled = false; | |
var SomeStore = module.exports = { | |
init: function (queryObject) { | |
if (_initCalled) | |
return; | |
_initCalled = true; | |
_query = queryObject; | |
}, | |
fetchData: function() { | |
var self = this; | |
this.someAjaxFn() | |
.then((result) => { | |
// process result... | |
SomeStore.notifyChange(); | |
}) | |
/** | |
* Catch XHR errors | |
*/ | |
.catch(APIRateLimitError, (err) => { | |
SomeStore.notifyChange(); | |
}); | |
}, | |
someAjaxFn: function() { | |
return new BPromise((resolve, reject) => { | |
var endpoint = 'http://api.domain.com/endpoint' | |
$.ajax({ | |
url: endpoint, | |
cache: true, | |
type: 'GET', | |
headers: { Accept: 'application/vnd.github.VERSION.raw' }, | |
success: (result) => { | |
resolve(result); | |
}, | |
error: (err) => { | |
this.checkResponseError(err.responseJSON, reject); | |
} | |
}); | |
}); | |
}, | |
checkResponseError: function (err, reject) { | |
if (err && err.message && err.message.indexOf('API rate limit') >= 0) { | |
reject(new APIRateLimitError()); | |
} else if (err && err.message == 'Not Found') { | |
reject(new AnotherError()); | |
} | |
return new Error(err); | |
}, | |
getData: function () { | |
return { | |
// return your data to component | |
} | |
}, | |
/** | |
* Listeners/Notifiers | |
*/ | |
notifyChange: function () { | |
_changeListeners.forEach(function (listener) { | |
listener(); | |
}); | |
}, | |
addChangeListener: function (listener) { | |
_changeListeners.push(listener); | |
}, | |
removeChangeListener: function (listener) { | |
_changeListeners = _changeListeners.filter(function (l) { | |
return listener !== l; | |
}); | |
}, | |
}; |
This file contains hidden or 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
import React from 'react'; | |
import SomeStore from './mystore-store.js'; | |
module.exports = MyComponent = React.createClass({ | |
/* Config (documentation) */ | |
propTypes: { | |
arrayProp: React.PropTypes.array, | |
boolProp: React.PropTypes.bool, | |
funcProp: React.PropTypes.func, | |
numProp: React.PropTypes.number, | |
objProp: React.PropTypes.object, | |
stringProp: React.PropTypes.string.isRequired, | |
}, | |
/* Init */ | |
getInitialState: function () { | |
return {} | |
}, | |
getDefaultProps: function () { | |
return {}; | |
}, | |
/* Mounting */ | |
componentWillMount: function () { | |
SomeStore.init(); | |
SomeStore.fetchData(); | |
}, | |
componentDidMount: function () { | |
SomeStore.addChangeListener(this._updateSomeState); | |
}, | |
/* Updating */ | |
componentWillReceiveProps: function(newProps={}) | |
shouldComponentUpdate: function((newProps={}, newState={}) | |
componentWillUpdate: function((newProps={}, newState={}) | |
componentDidUpdate: function((prevProps={}, prevState={}) | |
/* Unmounting */ | |
componentWillUnmount: function () { | |
SomeStore.removeChangeListener(this.updateGithubState); | |
}, | |
/* Helpers */ | |
_updateSomeState: function () { | |
this.setState(SomeStore.getData()); | |
}, | |
_parseQuerySearch: function() { }, | |
_resolveTemplate: function() { } | |
/* Render */ | |
// Multi-line JSX | |
render: function () { | |
return ( | |
<div> | |
{/* component markup */} | |
</div> | |
); | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment