Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save gilbox/8b4ca88518150bc4dcb9 to your computer and use it in GitHub Desktop.

Select an option

Save gilbox/8b4ca88518150bc4dcb9 to your computer and use it in GitHub Desktop.
Functional React: component Function with ComponentRenderMixin and staticFunctionsMixin
// ComponentRenderMixin is a slightly modified version of PureRenderMixin
const ComponentRenderMixin = require('component-render-mixin');
function delegate(delegee) {
var delegate = function() {
return delegate.delegee.apply(this, arguments);
}
delegate.delegee = delegee;
delegate.isDelegate = true;
return delegate;
}
function wrapWithDelegate (key) {
var statics = this;
var delegee = statics[key];
if (typeof delegee === 'function') {
statics[key] = isDelegate(delegee) ? delegee : delegate(delegee);
}
}
function isDelegate (value) {
return value && value.isDelegate;
}
function componentWillMount () {
var statics = this.props.statics;
if (statics && typeof statics === 'object') {
Object.keys(statics).forEach(wrapWithDelegate, statics);
}
}
function componentWillReceiveProps (newProps) {
var currentProps = this.props;
var currentStatics = currentProps.statics;
var newStatics = newProps.statics;
var haveChangedStatics = newStatics !== currentStatics &&
newStatics &&
typeof newStatics === 'object';
if (haveChangedStatics) {
Object.keys(newStatics).forEach(function(key) {
var newMember = newStatics[key];
if (typeof(newMember) == 'function') {
var currentMember = currentStatics && currentStatics[key];
if (isDelegate(currentMember)) {
var delegee = isDelegate(newMember) ? newMember.delegee : newMember;
currentMember.delegee = delegee;
newStatics[key] = currentMember;
} else {
newStatics[key] = delegate(newMember);
}
}
});
}
}
const staticFunctionsMixin = {
componentWillMount,
componentWillReceiveProps
};
// @param additionalMixins? {Array|Object}
// @param renderFn {Function}
// @returns Component
function component(additionalMixins, renderFn) {
renderFn = renderFn || additionalMixins;
additionalMixins = (additionalMixins instanceof Function) ? [] : [].concat(additionalMixins);
const mixins = [ComponentRenderMixin,
staticFunctionsMixin]
.concat(additionalMixins);
const render = function() {
console.log(`render <${renderFn.name} />`);
return renderFn.call(this, this.props, this.props.statics, this.props.children);
};
const displayName = renderFn.name;
return React.createClass({displayName, mixins, render});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment